diff --git a/CRM/Dataprocessor/BAO/DataProcessor.php b/CRM/Dataprocessor/BAO/DataProcessor.php
index c25dfef8001abb413464f340955ce3f906691412..d06e4bd334d0819aea284db7759a7293decd6107 100644
--- a/CRM/Dataprocessor/BAO/DataProcessor.php
+++ b/CRM/Dataprocessor/BAO/DataProcessor.php
@@ -1,179 +1,30 @@
 <?php
-/**
- * @author Jaap Jansma <jaap.jansma@civicoop.org>
- * @license AGPL-3.0
- */
+use CRM_Dataprocessor_ExtensionUtil as E;
 
 class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProcessor {
 
-  static $importingDataProcessors = array();
-
-  /**
-   * Function to get values
-   *
-   * @return array $result found rows with data
-   * @access public
-   * @static
-   */
-  public static function getValues($params) {
-    $result = array();
-    $dataProcessor = new CRM_Dataprocessor_DAO_DataProcessor();
-    if (!empty($params)) {
-      $fields = self::fields();
-      foreach ($params as $key => $value) {
-        if (isset($fields[$key])) {
-          $dataProcessor->$key = $value;
-        }
-      }
-    }
-    $dataProcessor->find();
-    while ($dataProcessor->fetch()) {
-      $row = array();
-      self::storeValues($dataProcessor, $row);
-      if (!empty($row['aggregation'])) {
-        $row['aggregation'] = json_decode($row['aggregation'], true);
-      } else {
-        $row['aggregation'] = array();
-      }
-      $result[$row['id']] = $row;
-    }
-    return $result;
-  }
-
-  /**
-   * Function to add or update a DataProcessor
-   *
-   * @param array $params
-   * @return array $result
-   * @access public
-   * @throws Exception when params is empty
-   * @static
-   */
-  public static function add($params) {
-    $result = array();
-    if (empty($params)) {
-      throw new Exception('Params can not be empty when adding or updating a data processor');
-    }
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::pre('edit', 'DataProcessor', $params['id'], $params);
-    }
-    else {
-      CRM_Utils_Hook::pre('create', 'DataProcessor', NULL, $params);
+  public static function checkName($title, $id=null,$name=null) {
+    if (!$name) {
+      $name = preg_replace('@[^a-z0-9_]+@','_',strtolower($title));
     }
 
-    $dataProcessor = new CRM_Dataprocessor_DAO_DataProcessor();
-    $fields = self::fields();
-    foreach ($params as $key => $value) {
-      if (isset($fields[$key])) {
-        $dataProcessor->$key = $value;
-      }
-    }
-    if (empty($dataProcessor->name) && !empty($dataProcessor->title)) {
-      $dataProcessor->name = self::buildNameFromTitle($dataProcessor->title);
-    }
-    if (empty($dataProcessor->type)) {
-      $dataProcessor->type = 'default';
-    }
-    if (isset($dataProcessor->configuration) && is_array($dataProcessor->configuration)) {
-      $dataProcessor->configuration = json_encode($dataProcessor->configuration);
-    }
-    if (isset($dataProcessor->aggregation) && is_array($dataProcessor->aggregation)) {
-      $dataProcessor->aggregation = json_encode($dataProcessor->aggregation);
-    }
-    if (isset($dataProcessor->storage_configuration) && is_array($dataProcessor->storage_configuration)) {
-      $dataProcessor->storage_configuration = json_encode($dataProcessor->storage_configuration);
-    }
-
-    $dataProcessor->save();
-    self::storeValues($dataProcessor, $result);
-    CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($dataProcessor->id);
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::post('edit', 'DataProcessor', $dataProcessor->id, $dataProcessor);
-    }
-    else {
-      CRM_Utils_Hook::post('create', 'DataProcessor', $dataProcessor->id, $dataProcessor);
-    }
+    $name = preg_replace('@[^a-z0-9_]+@','_',strtolower($name));
+    $name_part = $name;
 
-    return $result;
-  }
-
-  /**
-   * Function to delete a FormProcessorInstance with id
-   *
-   * @param int $id
-   * @throws Exception when $id is empty
-   * @access public
-   * @static
-   */
-  public static function deleteWithId($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to delete a data processor');
-    }
-
-    CRM_Utils_Hook::pre('delete', 'DataProcessor', $id, CRM_Core_DAO::$_nullArray);
-
-    CRM_Dataprocessor_BAO_Output::deleteWithDataProcessorId($id);
-    CRM_Dataprocessor_BAO_Filter::deleteWithDataProcessorId($id);
-    CRM_Dataprocessor_BAO_Field::deleteWithDataProcessorId($id);
-    CRM_Dataprocessor_BAO_Source::deleteWithDataProcessorId($id);
-
-    $dataProcessor = new CRM_Dataprocessor_DAO_DataProcessor();
-    $dataProcessor->id = $id;
-    $dataProcessor->delete();
-
-    CRM_Utils_Hook::post('delete', 'DataProcessor', $id, CRM_Core_DAO::$_nullArray);
-
-    return;
-  }
-
-  /**
-   * Function to disable a data processor
-   *
-   * @param int $id
-   * @throws Exception when id is empty
-   * @access public
-   * @static
-   */
-  public static function disable($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to disable a data processor');
+    $sql = "SELECT COUNT(*) FROM `civicrm_data_processor` WHERE `name` = %1";
+    $sqlParams[1] = array($name, 'String');
+    if ($id) {
+      $sql .= " AND `id` != %2";
+      $sqlParams[2] = array($id, 'Integer');
     }
-    $dataProcessor = new CRM_Dataprocessor_BAO_DataProcessor();
-    $dataProcessor->id = $id;
-    $dataProcessor->find(true);
-    self::add(array('id' => $dataProcessor->id, 'is_active' => 0));
-  }
 
-  /**
-   * Function to enable a data processor
-   *
-   * @param int $id
-   * @throws Exception when id is empty
-   * @access public
-   * @static
-   */
-  public static function enable($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to enable a data processor');
+    $i = 1;
+    while(CRM_Core_DAO::singleValueQuery($sql, $sqlParams) > 0) {
+      $i++;
+      $name = $name_part .'_'.$i;
+      $sqlParams[1] = array($name, 'String');
     }
-    $dataProcessor = new CRM_Dataprocessor_BAO_DataProcessor();
-    $dataProcessor->id = $id;
-    $dataProcessor->find(true);
-    self::add(array('id' => $dataProcessor->id, 'is_active' => 1));
-  }
-
-  /**
-   * Public function to generate name from title
-   *
-   * @param $label
-   * @return string
-   * @access public
-   * @static
-   */
-  public static function buildNameFromTitle($title) {
-    return preg_replace('@[^a-z0-9_]+@','_', strtolower($title));
+    return $name;
   }
 
   /**
@@ -185,10 +36,6 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc
    * @static
    */
   public static function isNameValid($name, $id=null) {
-    $invalidNames = array('getactions', 'getfields', 'get', 'create', 'delete');
-    if (in_array(strtolower($name), $invalidNames)) {
-      return false;
-    }
     $sql = "SELECT COUNT(*) FROM `civicrm_data_processor` WHERE `name` = %1";
     $params[1] = array($name, 'String');
     if ($id) {
@@ -202,282 +49,49 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc
   /**
    * Returns a configured data processor instance.
    *
-   * @param String $output_type
-   * @param String $name
-   * @return \Civi\DataProcessor\ProcessorType\AbstractProcessorType
-   * @throws \Exception when no data processor is found.
-   */
-  public static function getDataProcessorById($id) {
-    $sql = "
-      SELECT civicrm_data_processor.* 
-      FROM civicrm_data_processor 
-      WHERE id = %1
-    ";
-    $params[1] = [$id, 'Integer'];
-    $dao = CRM_Dataprocessor_BAO_DataProcessor::executeQuery($sql, $params, TRUE, 'CRM_Dataprocessor_BAO_DataProcessor');
-    if ($dao->N != 1) {
-      throw new \Exception('Could not find Data Processor');
-    }
-    $dao->fetch();
-    return $dao->getDataProcessor();
-  }
-
-  /**
-   * Returns a configured data processor instance.
-   *
-   * @param String $output_type
-   * @param String $name
+   * @param array $dataProcessor
    * @return \Civi\DataProcessor\ProcessorType\AbstractProcessorType
-   * @throws \Exception when no data processor is found.
+   * @throws \Exception
    */
-  public static function getDataProcessorByOutputTypeAndName($output_type, $name) {
-    $sql = "
-      SELECT civicrm_data_processor.* 
-      FROM civicrm_data_processor 
-      INNER JOIN civicrm_data_processor_output ON civicrm_data_processor.id = civicrm_data_processor_output.data_processor_id
-      WHERE is_active = 1 AND civicrm_data_processor.name = %1 AND civicrm_data_processor_output.type = %2
-    ";
-    $params[1] = array($name, 'String');
-    $params[2] = array($output_type, 'String');
-    $dao = CRM_Dataprocessor_BAO_DataProcessor::executeQuery($sql, $params, TRUE, 'CRM_Dataprocessor_BAO_DataProcessor');
-    if ($dao->N != 1) {
-      throw new \Exception('Could not find Data Processor');
-    }
-    $dao->fetch();
-    return $dao->getDataProcessor();
-  }
-
-  /**
-   * Returns a configured data processor instance.
-   *
-   * @return \Civi\DataProcessor\ProcessorType\AbstractProcessorType
-   */
-  public function getDataProcessor() {
+  public static function dataProcessorToClass($dataProcessor) {
     $factory = dataprocessor_get_factory();
-    $dataProcessor = $factory->getDataProcessorTypeByName($this->type);
-    $sources = CRM_Dataprocessor_BAO_Source::getValues(array('data_processor_id' => $this->id));
-    foreach($sources as $sourceDao) {
-      CRM_Dataprocessor_BAO_Source::getSourceClass($sourceDao, $dataProcessor);
+    $dataProcessorClass = $factory->getDataProcessorTypeByName($dataProcessor['type']);
+    $sources = civicrm_api3('DataProcessorSource', 'get', array('data_processor_id' => $dataProcessor['id'], 'options' => array('limit' => 0)));
+    foreach($sources['values'] as $sourceDao) {
+      CRM_Dataprocessor_BAO_DataProcessorSource::addSourceToDataProcessor($sourceDao, $dataProcessorClass);
     }
 
-    $aggregationFields = CRM_Dataprocessor_BAO_DataProcessor::getAvailableAggregationFields($this->id);
-    if (is_string($this->aggregation)) {
-      $this->aggregation = json_decode($this->aggregation, true);
+    $aggregationFields = array();
+    foreach($dataProcessorClass->getDataSources() as $source) {
+      $aggregationFields = array_merge($aggregationFields, $source->getAvailableAggregationFields());
     }
-    if (!is_array($this->aggregation)) {
-      $this->aggregation = array();
-    }
-    foreach($this->aggregation as $alias) {
-      $dataSource = $dataProcessor->getDataSourceByName($aggregationFields[$alias]->dataSource->getSourceName());
+    foreach($dataProcessor['aggregation'] as $alias) {
+      $dataSource = $dataProcessorClass->getDataSourceByName($aggregationFields[$alias]->dataSource->getSourceName());
       if ($dataSource) {
         $dataSource->ensureAggregationFieldInSource($aggregationFields[$alias]->fieldSpecification);
       }
     }
 
-    $filters = CRM_Dataprocessor_BAO_Filter::getValues(array('data_processor_id' => $this->id));
-    foreach($filters as $filter) {
+    $filters = civicrm_api3('DataProcessorFilter', 'get', array('data_processor_id' => $dataProcessor['id'], 'options' => array('limit' => 0)));
+    foreach($filters['values'] as $filter) {
       $filterHandler = $factory->getFilterByName($filter['type']);
       if ($filterHandler) {
-        $filterHandler->setDataProcessor($dataProcessor);
+        $filterHandler->setDataProcessor($dataProcessorClass);
         $filterHandler->initialize($filter['name'], $filter['title'], $filter['is_required'], $filter['configuration']);
-        $dataProcessor->addFilterHandler($filterHandler);
+        $dataProcessorClass->addFilterHandler($filterHandler);
       }
     }
 
-    $fields = CRM_Dataprocessor_BAO_Field::getValues(array('data_processor_id' => $this->id));
-    $outputHandlers = $dataProcessor->getAvailableOutputHandlers();
-    foreach($fields as $field) {
+    $fields = civicrm_api3('DataProcessorField', 'get', array('data_processor_id' => $dataProcessor['id'], 'options' => array('limit' => 0)));
+    $outputHandlers = $dataProcessorClass->getAvailableOutputHandlers();
+    foreach($fields['values'] as $field) {
       if (isset($outputHandlers[$field['type']])) {
         $outputHandler = $outputHandlers[$field['type']];
         $outputHandler->initialize($field['name'], $field['title'], $field['configuration']);
-        $dataProcessor->addOutputFieldHandlers($outputHandler);
-      }
-    }
-    return $dataProcessor;
-  }
-
-  public static function getAvailableOutputHandlers($data_processor_id) {
-    $dao = new CRM_Dataprocessor_BAO_DataProcessor();
-    $dao->id = $data_processor_id;
-    $dao->find(true);
-    $factory = dataprocessor_get_factory();
-    $dataProcessor = $factory->getDataProcessorTypeByName($dao->type);
-    $sources = CRM_Dataprocessor_BAO_Source::getValues(array('data_processor_id' => $dao->id));
-    foreach($sources as $sourceDao) {
-      CRM_Dataprocessor_BAO_Source::getSourceClass($sourceDao, $dataProcessor);
-    }
-
-    return $dataProcessor->getAvailableOutputHandlers();
-  }
-
-  public static function getAvailableFilterHandlers($data_processor_id) {
-    $dao = new CRM_Dataprocessor_BAO_DataProcessor();
-    $dao->id = $data_processor_id;
-    $dao->find(true);
-    $factory = dataprocessor_get_factory();
-    $dataProcessor = $factory->getDataProcessorTypeByName($dao->type);
-    $sources = CRM_Dataprocessor_BAO_Source::getValues(array('data_processor_id' => $dao->id));
-    foreach($sources as $sourceDao) {
-      CRM_Dataprocessor_BAO_Source::getSourceClass($sourceDao, $dataProcessor);
-    }
-
-    return $dataProcessor->getAvailableFilterHandlers();
-  }
-
-  /**
-   * Returns an array with all available fields for aggregation
-   *
-   * @param $data_processor_id
-   *
-   * @return array
-   */
-  public static function getAvailableAggregationFields($data_processor_id) {
-    $availableAggregationFields = array();
-    $dao = new CRM_Dataprocessor_BAO_DataProcessor();
-    $dao->id = $data_processor_id;
-    $dao->find(true);
-    $factory = dataprocessor_get_factory();
-    $dataProcessor = $factory->getDataProcessorTypeByName($dao->type);
-    $sources = CRM_Dataprocessor_BAO_Source::getValues(array('data_processor_id' => $dao->id));
-    foreach($sources as $sourceDao) {
-      $source = CRM_Dataprocessor_BAO_Source::getSourceClass($sourceDao, $dataProcessor);
-      $availableAggregationFields = array_merge($availableAggregationFields, $source->getAvailableAggregationFields());
-    }
-
-    return $availableAggregationFields;
-  }
-
-  /**
-   * Returns the id of the data processor.
-   *
-   * @param string $dataProcessorName
-   *   The name of the data processor.
-   * @return int
-   *   The id of the data processor.
-   */
-  public static function getId($dataProcessorName) {
-    $sql = "SELECT `id` FROM `civicrm_data_processor` WHERE `name` = %1";
-    $params[1] = array($dataProcessorName, 'String');
-    $id = CRM_Core_DAO::singleValueQuery($sql, $params);
-    return $id;
-  }
-
-  /**
-   * Returns the status of the data processor.
-   * @See CRM_Dataprocessor_DAO_DataProcessor for possible values.
-   *
-   * @param string $dataProcessorName
-   *   The name of the data processor.
-   * @return int
-   *   The status of the data processor.
-   */
-  public static function getStatus($dataProcessorName) {
-    $sql = "SELECT `status` FROM `civicrm_data_processor` WHERE `name` = %1";
-    $params[1] = array($dataProcessorName, 'String');
-    $status = CRM_Core_DAO::singleValueQuery($sql, $params);
-    return $status;
-  }
-
-  /**
-   * Update the status from in code to overriden when a data processor has been changed
-   *
-   * @param $dataProcessorId
-   */
-  public static function updateAndChekStatus($dataProcessorId) {
-    $sql = "SELECT `status`, `name` FROM `civicrm_data_processor` WHERE `id` = %1";
-    $params[1] = array($dataProcessorId, 'Integer');
-    $dao = CRM_Core_DAO::executeQuery($sql, $params);
-    if ($dao->fetch()) {
-      if (!in_array($dao->name, self::$importingDataProcessors) && $dao->status == self::STATUS_IN_CODE) {
-        $sql = "UPDATE `civicrm_data_processor` SET `status` = %2 WHERE `id` = %1";
-        $params[1] = array($dataProcessorId, 'String');
-        $params[2] = array(self::STATUS_OVERRIDDEN, 'Integer');
-        CRM_Core_DAO::executeQuery($sql, $params);
+        $dataProcessorClass->addOutputFieldHandlers($outputHandler);
       }
     }
-  }
-
-  /**
-   * Store the data processor name so we know that we are importing this data processor
-   * and should not update its status on the way.
-   *
-   * @param $dataProcessorName
-   */
-  public static function setDataProcessorToImportingState($dataProcessorName) {
-    self::$importingDataProcessors[] = $dataProcessorName;
-  }
-
-  /**
-   * Updates the status and source file of the data processor.
-   * @See CRM_Dataprocessor_DAO_DataProcessor for possible status values.
-   *
-   * @param string $dataProcessorName
-   *   The name of the data processor.
-   * @param int $status
-   *   The status value.
-   * @param string $source_file
-   *   The source file. Leave empty when status is IN_DATABASE.
-   */
-  public static function setStatusAndSourceFile($dataProcessorName, $status, $source_file) {
-    $sql = "UPDATE `civicrm_data_processor` SET `status` = %2, `source_file` = %3 WHERE `name` = %1";
-    $params[1] = array($dataProcessorName, 'String');
-    $params[2] = array($status, 'Integer');
-    $params[3] = array($source_file, 'String');
-    CRM_Core_DAO::executeQuery($sql, $params);
-  }
-
-  /**
-   * Exports a data processor
-   *
-   * Returns the array with the whole configuration.
-   *
-   * @param $id
-   * @return array
-   */
-  public static function export($id) {
-    $dataProcessors = self::getValues(array('id' => $id));
-    if (!isset($dataProcessors[$id])) {
-      return array();
-    }
-    $dataProcessor = $dataProcessors[$id];
-    unset($dataProcessor['id']);
-    unset($dataProcessor['status']);
-    unset($dataProcessor['source_file']);
-
-    $dataSources = CRM_Dataprocessor_BAO_Source::getValues(array('data_processor_id' => $id));
-    $dataProcessor['data_sources'] = array();
-    foreach($dataSources as $i => $datasource) {
-      unset($datasource['id']);
-      unset($datasource['data_processor_id']);
-      $dataProcessor['data_sources'][] = $datasource;
-    }
-    $filters = CRM_Dataprocessor_BAO_Filter::getValues(array('data_processor_id' => $id));
-    $dataProcessor['filters']  = array();
-    foreach($filters as $i => $filter) {
-      unset($filter['id']);
-      unset($filter['data_processor_id']);
-      $dataProcessor['filters'][] = $filter;
-    }
-    $fields = CRM_Dataprocessor_BAO_Field::getValues(array('data_processor_id' => $id));
-    $dataProcessor['fields'] = array();
-    foreach($fields as $i => $field) {
-      unset($field['id']);
-      unset($field['data_processor_id']);
-      $dataProcessor['fields'][] = $field;
-    }
-    $outputs = CRM_Dataprocessor_BAO_Output::getValues(array('data_processor_id' => $id));
-    $dataProcessor['outputs'] = array();
-    foreach($outputs as $i => $output) {
-      unset($output['id']);
-      unset($output['data_processor_id']);
-      $dataProcessor['outputs'][] = $output;
-    }
-
-    $eventData['data_processor'] = &$dataProcessor;
-    $event = \Civi\Core\Event\GenericHookEvent::create($eventData);
-    \Civi::dispatcher()->dispatch('hook_civicrm_dataprocessor_export', $event);
-
-    return $dataProcessor;
+    return $dataProcessorClass;
   }
 
   /**
@@ -488,7 +102,7 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc
     if (!$dao->fetch()) {
       return false;
     }
-    if ($dao->status != CRM_Dataprocessor_DAO_DataProcessor::STATUS_OVERRIDDEN) {
+    if ($dao->status != CRM_Dataprocessor_Status::STATUS_OVERRIDDEN) {
       return false;
     }
     $key = substr($dao->source_file, 0, stripos($dao->source_file, "/"));
@@ -497,8 +111,8 @@ class CRM_Dataprocessor_BAO_DataProcessor extends CRM_Dataprocessor_DAO_DataProc
     $data = file_get_contents($filename);
     $data = json_decode($data, true);
 
-    CRM_Dataprocessor_Utils_Importer::importDataProcessor($data, $dao->source_file, $data_processor_id);
+    CRM_Dataprocessor_Utils_Importer::importDataProcessor($data, $dao->source_file, $data_processor_id, CRM_Dataprocessor_Status::STATUS_IN_CODE);
     return true;
   }
 
-}
\ No newline at end of file
+}
diff --git a/CRM/Dataprocessor/BAO/DataProcessorField.php b/CRM/Dataprocessor/BAO/DataProcessorField.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a2806e5f32e340f662ece38af2a7f401f6c7be7
--- /dev/null
+++ b/CRM/Dataprocessor/BAO/DataProcessorField.php
@@ -0,0 +1,52 @@
+<?php
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+class CRM_Dataprocessor_BAO_DataProcessorField extends CRM_Dataprocessor_DAO_DataProcessorField {
+
+  public static function checkName($title, $data_processor_id, $id=null,$name=null) {
+    if (!$name) {
+      $name = preg_replace('@[^a-z0-9_]+@','_',strtolower($title));
+    }
+
+    $name = preg_replace('@[^a-z0-9_]+@','_',strtolower($name));
+    $name_part = $name;
+
+    $sql = "SELECT COUNT(*) FROM `civicrm_data_processor_field` WHERE `name` = %1 AND `data_processor_id` = %2";
+    $sqlParams[1] = array($name, 'String');
+    $sqlParams[2] = array($data_processor_id, 'String');
+    if ($id) {
+      $sql .= " AND `id` != %3";
+      $sqlParams[3] = array($id, 'Integer');
+    }
+
+    $i = 1;
+    while(CRM_Core_DAO::singleValueQuery($sql, $sqlParams) > 0) {
+      $i++;
+      $name = $name_part .'_'.$i;
+      $sqlParams[1] = array($name, 'String');
+    }
+    return $name;
+  }
+
+  /**
+   * Function to delete a Data Processor Filter with id
+   *
+   * @param int $id
+   * @throws Exception when $id is empty
+   * @access public
+   * @static
+   */
+  public static function deleteWithDataProcessorId($id) {
+    if (empty($id)) {
+      throw new Exception('id can not be empty when attempting to delete a data processor filter');
+    }
+
+    $field = new CRM_Dataprocessor_DAO_DataProcessorField();
+    $field->data_processor_id = $id;
+    $field->find(FALSE);
+    while ($field->fetch()) {
+      civicrm_api3('DataProcessorField', 'delete', array('id' => $field->id));
+    }
+  }
+
+}
diff --git a/CRM/Dataprocessor/BAO/DataProcessorFilter.php b/CRM/Dataprocessor/BAO/DataProcessorFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..88b0d039aaa75962e906e8c99a976032b29c96cd
--- /dev/null
+++ b/CRM/Dataprocessor/BAO/DataProcessorFilter.php
@@ -0,0 +1,52 @@
+<?php
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+class CRM_Dataprocessor_BAO_DataProcessorFilter extends CRM_Dataprocessor_DAO_DataProcessorFilter {
+
+  public static function checkName($title, $data_processor_id, $id=null,$name=null) {
+    if (!$name) {
+      $name = preg_replace('@[^a-z0-9_]+@','_',strtolower($title));
+    }
+
+    $name = preg_replace('@[^a-z0-9_]+@','_',strtolower($name));
+    $name_part = $name;
+
+    $sql = "SELECT COUNT(*) FROM `civicrm_data_processor_filter` WHERE `name` = %1 AND `data_processor_id` = %2";
+    $sqlParams[1] = array($name, 'String');
+    $sqlParams[2] = array($data_processor_id, 'String');
+    if ($id) {
+      $sql .= " AND `id` != %3";
+      $sqlParams[3] = array($id, 'Integer');
+    }
+
+    $i = 1;
+    while(CRM_Core_DAO::singleValueQuery($sql, $sqlParams) > 0) {
+      $i++;
+      $name = $name_part .'_'.$i;
+      $sqlParams[1] = array($name, 'String');
+    }
+    return $name;
+  }
+
+  /**
+   * Function to delete a Data Processor Filter with id
+   *
+   * @param int $id
+   * @throws Exception when $id is empty
+   * @access public
+   * @static
+   */
+  public static function deleteWithDataProcessorId($id) {
+    if (empty($id)) {
+      throw new Exception('id can not be empty when attempting to delete a data processor filter');
+    }
+
+    $field = new CRM_Dataprocessor_DAO_DataProcessorFilter();
+    $field->data_processor_id = $id;
+    $field->find(FALSE);
+    while ($field->fetch()) {
+      civicrm_api3('DataProcessorFilter', 'delete', array('id' => $field->id));
+    }
+  }
+
+}
diff --git a/CRM/Dataprocessor/BAO/DataProcessorOutput.php b/CRM/Dataprocessor/BAO/DataProcessorOutput.php
new file mode 100644
index 0000000000000000000000000000000000000000..049a96dd2d3e66660b568b6fed0b280237fa3a90
--- /dev/null
+++ b/CRM/Dataprocessor/BAO/DataProcessorOutput.php
@@ -0,0 +1,27 @@
+<?php
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+class CRM_Dataprocessor_BAO_DataProcessorOutput extends CRM_Dataprocessor_DAO_DataProcessorOutput {
+
+  /**
+   * Function to delete a Data Processor Output with id
+   *
+   * @param int $id
+   * @throws Exception when $id is empty
+   * @access public
+   * @static
+   */
+  public static function deleteWithDataProcessorId($id) {
+    if (empty($id)) {
+      throw new Exception('id can not be empty when attempting to delete a data processor filter');
+    }
+
+    $field = new CRM_Dataprocessor_DAO_DataProcessorOutput();
+    $field->data_processor_id = $id;
+    $field->find(FALSE);
+    while ($field->fetch()) {
+      civicrm_api3('DataProcessorOutput', 'delete', array('id' => $field->id));
+    }
+  }
+
+}
diff --git a/CRM/Dataprocessor/BAO/DataProcessorSource.php b/CRM/Dataprocessor/BAO/DataProcessorSource.php
new file mode 100644
index 0000000000000000000000000000000000000000..6a0dd3bd32b340425de9fdc573769cad42b47d0b
--- /dev/null
+++ b/CRM/Dataprocessor/BAO/DataProcessorSource.php
@@ -0,0 +1,116 @@
+<?php
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+class CRM_Dataprocessor_BAO_DataProcessorSource extends CRM_Dataprocessor_DAO_DataProcessorSource {
+
+  public static function checkName($title, $data_processor_id, $id=null,$name=null) {
+    if (!$name) {
+      $name = preg_replace('@[^a-z0-9_]+@','_',strtolower($title));
+    }
+
+    $name = preg_replace('@[^a-z0-9_]+@','_',strtolower($name));
+    $name_part = $name;
+
+    $sql = "SELECT COUNT(*) FROM `civicrm_data_processor_source` WHERE `name` = %1 AND `data_processor_id` = %2";
+    $sqlParams[1] = array($name, 'String');
+    $sqlParams[2] = array($data_processor_id, 'String');
+    if ($id) {
+      $sql .= " AND `id` != %3";
+      $sqlParams[3] = array($id, 'Integer');
+    }
+
+    $i = 1;
+    while(CRM_Core_DAO::singleValueQuery($sql, $sqlParams) > 0) {
+      $i++;
+      $name = $name_part .'_'.$i;
+      $sqlParams[1] = array($name, 'String');
+    }
+    return $name;
+  }
+
+  /**
+   * Returns whether the name is valid or not
+   *
+   * @param string $name
+   * @param int $data_procssor_id,
+   * @param int $id optional
+   * @return bool
+   * @static
+   */
+  public static function isNameValid($name, $data_procssor_id, $id=null) {
+    $sql = "SELECT COUNT(*) FROM `civicrm_data_processor_source` WHERE `name` = %1 AND `data_processor_id` = %2";
+    $params[1] = array($name, 'String');
+    $params[2] = array($data_procssor_id, 'Integer');
+    if ($id) {
+      $sql .= " AND `id` != %3";
+      $params[3] = array($id, 'Integer');
+    }
+    $count = CRM_Core_DAO::singleValueQuery($sql, $params);
+    return ($count > 0) ? false : true;
+  }
+
+  /**
+   * Function to delete a Data Processor Source with id
+   *
+   * @param int $id
+   * @throws Exception when $id is empty
+   * @access public
+   * @static
+   */
+  public static function deleteWithDataProcessorId($id) {
+    if (empty($id)) {
+      throw new Exception('id can not be empty when attempting to delete a data processor filter');
+    }
+
+    $field = new CRM_Dataprocessor_DAO_DataProcessorSource();
+    $field->data_processor_id = $id;
+    $field->find(FALSE);
+    while ($field->fetch()) {
+      civicrm_api3('DataProcessorSource', 'delete', array('id' => $field->id));
+    }
+  }
+
+  /**
+   * @param $source
+   * @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor
+   * @return \Civi\DataProcessor\Source\SourceInterface
+   */
+  public static function addSourceToDataProcessor($source, \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor) {
+    $factory = dataprocessor_get_factory();
+    $sourceClass = self::sourceToSourceClass($source);
+    $sourceClass->setDataProcessor($dataProcessor);
+    $join = null;
+    if (isset($source['join_type']) && $source['join_type']) {
+      $join = $factory->getJoinByName($source['join_type']);
+      $join->setConfiguration($source['join_configuration']);
+      $join->setDataProcessor($dataProcessor);
+    }
+    $dataProcessor->addDataSource($sourceClass, $join);
+    if ($join) {
+      $join->initialize();
+      $sourceClass->setJoin($join);
+    }
+    return $sourceClass;
+  }
+
+  /**
+   * Converts a Source array to an instanciated source class.
+   *
+   * @param $source
+   * @return \Civi\DataProcessor\Source\SourceInterface
+   */
+  public static function sourceToSourceClass($source) {
+    $factory = dataprocessor_get_factory();
+    $sourceClass = $factory->getDataSourceByName($source['type']);
+    if (isset($source['name'])) {
+      $sourceClass->setSourceName($source['name']);
+    }
+    if (isset($source['title'])) {
+      $sourceClass->setSourceTitle($source['title']);
+    }
+    if (isset($source['configuration'])) {
+      $sourceClass->setConfiguration($source['configuration']);
+    }
+    return $sourceClass;
+  }
+}
diff --git a/CRM/Dataprocessor/BAO/Field.php b/CRM/Dataprocessor/BAO/Field.php
deleted file mode 100644
index 1253658206d8e8c61917242149953e3cf2941002..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/BAO/Field.php
+++ /dev/null
@@ -1,190 +0,0 @@
-<?php
-/**
- * @author Jaap Jansma <jaap.jansma@civicoop.org>
- * @license AGPL-3.0
- */
-
-class CRM_Dataprocessor_BAO_Field extends CRM_Dataprocessor_DAO_Field {
-
-  /**
-   * Function to get values
-   *
-   * @return array $result found rows with data
-   * @access public
-   * @static
-   */
-  public static function getValues($params) {
-    $factory = dataprocessor_get_factory();
-    $types = $factory->getDataSources();
-
-    $result = array();
-    $field = new CRM_Dataprocessor_DAO_Field();
-    if (!empty($params)) {
-      $fields = self::fields();
-      foreach ($params as $key => $value) {
-        if (isset($fields[$key])) {
-          $field->$key = $value;
-        }
-      }
-    }
-    $field->orderBy("weight ASC");
-    $field->find();
-    while ($field->fetch()) {
-      $row = array();
-      self::storeValues($field, $row);
-
-      if (isset($types[$row['type']])) {
-        $row['type_name'] = $types[$row['type']];
-      } else {
-        $row['type_name'] = '';
-      }
-      if (!empty($row['configuration'])) {
-        $row['configuration'] = json_decode($row['configuration'], true);
-      } else {
-        $row['configuration'] = array();
-      }
-      if (!empty($row['join_configuration'])) {
-        $row['join_configuration'] = json_decode($row['join_configuration'], true);
-      } else {
-        $row['join_configuration'] = array();
-      }
-
-      $result[$row['id']] = $row;
-    }
-    return $result;
-  }
-
-  /**
-   * Function to add or update a DataProcessor
-   *
-   * @param array $params
-   * @return array $result
-   * @access public
-   * @throws Exception when params is empty
-   * @static
-   */
-  public static function add($params) {
-    $result = array();
-    if (empty($params)) {
-      throw new Exception('Params can not be empty when adding or updating a data processor field');
-    }
-
-    if (!isset($params['weight'])) {
-      $params['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Dataprocessor_DAO_Field', array('data_processor_id' => $params['data_processor_id']));
-    }
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::pre('edit', 'DataProcessorField', $params['id'], $params);
-    }
-    else {
-      CRM_Utils_Hook::pre('create', 'DataProcessorField', NULL, $params);
-    }
-
-    $field = new CRM_Dataprocessor_DAO_Field();
-    $fields = self::fields();
-    foreach ($params as $key => $value) {
-      if (isset($fields[$key])) {
-        $field->$key = $value;
-      }
-    }
-    if (isset($field->configuration) && is_array($field->configuration)) {
-      $field->configuration = json_encode($field->configuration);
-    }
-
-    $field->save();
-    $id = $field->id;
-    $field = new CRM_Dataprocessor_BAO_Field();
-    $field->id = $id;
-    $field->find(true);
-    CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($field->data_processor_id);
-    self::storeValues($field, $result);
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::post('edit', 'DataProcessorField', $field->id, $field);
-    }
-    else {
-      CRM_Utils_Hook::post('create', 'DataProcessorField', $field->id, $field);
-    }
-
-    return $result;
-  }
-
-  /**
-   * Public function to generate name from title
-   *
-   * @param $label
-   * @return string
-   * @access public
-   * @static
-   */
-  public static function buildNameFromTitle($title) {
-    return preg_replace('@[^a-z0-9_]+@','_', strtolower($title));
-  }
-
-  /**
-   * Returns whether the name is valid or not
-   *
-   * @param string $name
-   * @param int $data_procssor_id,
-   * @param int $id optional
-   * @return bool
-   * @static
-   */
-  public static function isNameValid($name, $data_procssor_id, $id=null) {
-    $sql = "SELECT COUNT(*) FROM `civicrm_data_processor_field` WHERE `name` = %1 AND `data_processor_id` = %2";
-    $params[1] = array($name, 'String');
-    $params[2] = array($data_procssor_id, 'Integer');
-    if ($id) {
-      $sql .= " AND `id` != %3";
-      $params[3] = array($id, 'Integer');
-    }
-    $count = CRM_Core_DAO::singleValueQuery($sql, $params);
-    return ($count > 0) ? false : true;
-  }
-
-  /**
-   * Function to delete a Data Processor Field with id
-   *
-   * @param int $id
-   * @throws Exception when $id is empty
-   * @access public
-   * @static
-   */
-  public static function deleteWithId($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to delete a data processor field');
-    }
-
-    CRM_Utils_Hook::pre('delete', 'DataProcessorField', $id, CRM_Core_DAO::$_nullArray);
-
-    $field = new CRM_Dataprocessor_DAO_Field();
-    $field->id = $id;
-    $field->delete();
-
-    CRM_Utils_Hook::post('delete', 'DataProcessorField', $id, CRM_Core_DAO::$_nullArray);
-
-    return;
-  }
-
-  /**
-   * Function to delete a Data Processor Field with id
-   *
-   * @param int $id
-   * @throws Exception when $id is empty
-   * @access public
-   * @static
-   */
-  public static function deleteWithDataProcessorId($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to delete a data processor field');
-    }
-
-    $field = new CRM_Dataprocessor_DAO_Field();
-    $field->data_processor_id = $id;
-    $field->find(FALSE);
-    while ($field->fetch()) {
-      self::deleteWithId($field->id);
-    }
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/BAO/Filter.php b/CRM/Dataprocessor/BAO/Filter.php
deleted file mode 100644
index 3f034800f2af7d570c6cddd7f7c5568376a86c9c..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/BAO/Filter.php
+++ /dev/null
@@ -1,180 +0,0 @@
-<?php
-/**
- * @author Jaap Jansma <jaap.jansma@civicoop.org>
- * @license AGPL-3.0
- */
-
-class CRM_Dataprocessor_BAO_Filter extends CRM_Dataprocessor_DAO_Filter {
-
-  /**
-   * Function to get values
-   *
-   * @return array $result found rows with data
-   * @access public
-   * @static
-   */
-  public static function getValues($params) {
-    $factory = dataprocessor_get_factory();
-    $types = $factory->getDataSources();
-
-    $result = array();
-    $filter = new CRM_Dataprocessor_DAO_Filter();
-    if (!empty($params)) {
-      $filters = self::fields();
-      foreach ($params as $key => $value) {
-        if (isset($filters[$key])) {
-          $filter->$key = $value;
-        }
-      }
-    }
-    $filter->find();
-    while ($filter->fetch()) {
-      $row = array();
-      self::storeValues($filter, $row);
-
-      if (isset($types[$row['type']])) {
-        $row['type_name'] = $types[$row['type']];
-      } else {
-        $row['type_name'] = '';
-      }
-      if (!empty($row['configuration'])) {
-        $row['configuration'] = json_decode($row['configuration'], true);
-      } else {
-        $row['configuration'] = array();
-      }
-
-      $result[$row['id']] = $row;
-    }
-    return $result;
-  }
-
-  /**
-   * Function to add or update a DataProcessor
-   *
-   * @param array $params
-   * @return array $result
-   * @access public
-   * @throws Exception when params is empty
-   * @static
-   */
-  public static function add($params) {
-    $result = array();
-    if (empty($params)) {
-      throw new Exception('Params can not be empty when adding or updating a data processor filter');
-    }
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::pre('edit', 'DataProcessorFilter', $params['id'], $params);
-    }
-    else {
-      CRM_Utils_Hook::pre('create', 'DataProcessorFilter', NULL, $params);
-    }
-
-    $filter = new CRM_Dataprocessor_DAO_Filter();
-    $filters = self::fields();
-    foreach ($params as $key => $value) {
-      if (isset($filters[$key])) {
-        $filter->$key = $value;
-      }
-    }
-    if (isset($filter->configuration) && is_array($filter->configuration)) {
-      $filter->configuration = json_encode($filter->configuration);
-    }
-
-    $filter->save();
-    $id = $filter->id;
-    $filter = new CRM_Dataprocessor_BAO_Filter();
-    $filter->id = $id;
-    $filter->find(true);
-    CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($filter->data_processor_id);
-    self::storeValues($filter, $result);
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::post('edit', 'DataProcessorFilter', $filter->id, $filter);
-    }
-    else {
-      CRM_Utils_Hook::post('create', 'DataProcessorFilter', $filter->id, $filter);
-    }
-
-    return $result;
-  }
-
-  /**
-   * Public function to generate name from title
-   *
-   * @param $label
-   * @return string
-   * @access public
-   * @static
-   */
-  public static function buildNameFromTitle($title) {
-    return preg_replace('@[^a-z0-9_]+@','_', strtolower($title));
-  }
-
-  /**
-   * Returns whether the name is valid or not
-   *
-   * @param string $name
-   * @param int $data_procssor_id,
-   * @param int $id optional
-   * @return bool
-   * @static
-   */
-  public static function isNameValid($name, $data_procssor_id, $id=null) {
-    $sql = "SELECT COUNT(*) FROM `civicrm_data_processor_filter` WHERE `name` = %1 AND `data_processor_id` = %2";
-    $params[1] = array($name, 'String');
-    $params[2] = array($data_procssor_id, 'Integer');
-    if ($id) {
-      $sql .= " AND `id` != %3";
-      $params[3] = array($id, 'Integer');
-    }
-    $count = CRM_Core_DAO::singleValueQuery($sql, $params);
-    return ($count > 0) ? false : true;
-  }
-
-  /**
-   * Function to delete a Data Processor Filter with id
-   *
-   * @param int $id
-   * @throws Exception when $id is empty
-   * @access public
-   * @static
-   */
-  public static function deleteWithId($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to delete a data processor filter');
-    }
-
-    CRM_Utils_Hook::pre('delete', 'DataProcessorFilter', $id, CRM_Core_DAO::$_nullArray);
-
-    $filter = new CRM_Dataprocessor_DAO_Filter();
-    $filter->id = $id;
-    $filter->delete();
-
-    CRM_Utils_Hook::post('delete', 'DataProcessorFilter', $id, CRM_Core_DAO::$_nullArray);
-
-    return;
-  }
-
-  /**
-   * Function to delete a Data Processor Filter with id
-   *
-   * @param int $id
-   * @throws Exception when $id is empty
-   * @access public
-   * @static
-   */
-  public static function deleteWithDataProcessorId($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to delete a data processor filter');
-    }
-
-    $filter = new CRM_Dataprocessor_DAO_Filter();
-    $filter->data_processor_id = $id;
-    $filter->find(FALSE);
-    while ($filter->fetch()) {
-      self::deleteWithId($filter->id);
-    }
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/BAO/Output.php b/CRM/Dataprocessor/BAO/Output.php
deleted file mode 100644
index 7b3fc979ad8ed1c20a870e75fc48e57c69958d02..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/BAO/Output.php
+++ /dev/null
@@ -1,151 +0,0 @@
-<?php
-/**
- * @author Jaap Jansma <jaap.jansma@civicoop.org>
- * @license AGPL-3.0
- */
-
-class CRM_Dataprocessor_BAO_Output extends CRM_Dataprocessor_DAO_Output {
-
-  /**
-   * Function to get values
-   *
-   * @return array $result found rows with data
-   * @access public
-   * @static
-   */
-  public static function getValues($params) {
-    $factory = dataprocessor_get_factory();
-    $types = $factory->getOutputs();
-
-    $result = array();
-    $output = new CRM_Dataprocessor_DAO_Output();
-    if (!empty($params)) {
-      $fields = self::fields();
-      foreach ($params as $key => $value) {
-        if (isset($fields[$key])) {
-          $output->$key = $value;
-        }
-      }
-    }
-    $output->find();
-    while ($output->fetch()) {
-      $row = array();
-      self::storeValues($output, $row);
-
-      if (isset($types[$row['type']])) {
-        $row['type_name'] = $types[$row['type']];
-      } else {
-        $row['type_name'] = '';
-      }
-
-      if (isset($row['configuration']) && is_string($row['configuration']) && strlen($row['configuration'])) {
-        $row['configuration'] = json_decode($row['configuration'], true);
-      } else {
-        $row['configuration'] = array();
-      }
-
-      $result[$row['id']] = $row;
-    }
-    return $result;
-  }
-
-  /**
-   * Function to add or update a DataProcessor
-   *
-   * @param array $params
-   * @return array $result
-   * @access public
-   * @throws Exception when params is empty
-   * @static
-   */
-  public static function add($params) {
-    $result = array();
-    if (empty($params)) {
-      throw new Exception('Params can not be empty when adding or updating a data processor output');
-    }
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::pre('edit', 'DataProcessorOutput', $params['id'], $params);
-    }
-    else {
-      CRM_Utils_Hook::pre('create', 'DataProcessorOutput', NULL, $params);
-    }
-
-    $output = new CRM_Dataprocessor_DAO_Output();
-    $fields = self::fields();
-    foreach ($params as $key => $value) {
-      if (isset($fields[$key])) {
-        $output->$key = $value;
-      }
-    }
-    if (!isset($output->configuration)) {
-      $output->configuration = array();
-    }
-    if (is_array($output->configuration)) {
-      $output->configuration = json_encode($output->configuration);
-    }
-
-    $output->save();
-    $id = $output->id;
-    $output = new CRM_Dataprocessor_BAO_Output();
-    $output->id = $id;
-    $output->find(true);
-    CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($output->data_processor_id);
-    self::storeValues($output, $result);
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::post('edit', 'DataProcessorOutput', $output->id, $output);
-    }
-    else {
-      CRM_Utils_Hook::post('create', 'DataProcessorOutput', $output->id, $output);
-    }
-
-    return $result;
-  }
-
-  /**
-   * Function to delete a Data Processor Output with id
-   *
-   * @param int $id
-   * @throws Exception when $id is empty
-   * @access public
-   * @static
-   */
-  public static function deleteWithId($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to delete a data processor output');
-    }
-
-    CRM_Utils_Hook::pre('delete', 'DataProcessorOutput', $id, CRM_Core_DAO::$_nullArray);
-
-    $output = new CRM_Dataprocessor_DAO_Output();
-    $output->id = $id;
-    $output->delete();
-
-    CRM_Utils_Hook::post('delete', 'DataProcessorOutput', $id, CRM_Core_DAO::$_nullArray);
-
-    return;
-  }
-
-  /**
-   * Function to delete a Data Processor Output with id
-   *
-   * @param int $id
-   * @throws Exception when $id is empty
-   * @access public
-   * @static
-   */
-  public static function deleteWithDataProcessorId($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to delete a data processor output');
-    }
-
-    $output = new CRM_Dataprocessor_DAO_Output();
-    $output->data_processor_id = $id;
-    $output->find(FALSE);
-    while ($output->fetch()) {
-      self::deleteWithId($output->id);
-    }
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/BAO/Source.php b/CRM/Dataprocessor/BAO/Source.php
deleted file mode 100644
index e2914b06dd5b7a9ba8308b18d1e5bb94d894025b..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/BAO/Source.php
+++ /dev/null
@@ -1,214 +0,0 @@
-<?php
-/**
- * @author Jaap Jansma <jaap.jansma@civicoop.org>
- * @license AGPL-3.0
- */
-
-class CRM_Dataprocessor_BAO_Source extends CRM_Dataprocessor_DAO_Source {
-
-  /**
-   * Function to get values
-   *
-   * @return array $result found rows with data
-   * @access public
-   * @static
-   */
-  public static function getValues($params) {
-    $factory = dataprocessor_get_factory();
-    $types = $factory->getDataSources();
-
-    $result = array();
-    $source = new CRM_Dataprocessor_DAO_Source();
-    if (!empty($params)) {
-      $fields = self::fields();
-      foreach ($params as $key => $value) {
-        if (isset($fields[$key])) {
-          $source->$key = $value;
-        }
-      }
-    }
-    $source->find();
-    while ($source->fetch()) {
-      $row = array();
-      self::storeValues($source, $row);
-
-      if (isset($types[$row['type']])) {
-        $row['type_name'] = $types[$row['type']];
-      } else {
-        $row['type_name'] = '';
-      }
-      if (!empty($row['configuration'])) {
-        $row['configuration'] = json_decode($row['configuration'], true);
-      } else {
-        $row['configuration'] = array();
-      }
-      if (!empty($row['join_configuration'])) {
-        $row['join_configuration'] = json_decode($row['join_configuration'], true);
-      } else {
-        $row['join_configuration'] = array();
-      }
-
-      $result[$row['id']] = $row;
-    }
-    return $result;
-  }
-
-  /**
-   * Function to add or update a DataProcessor
-   *
-   * @param array $params
-   * @return array $result
-   * @access public
-   * @throws Exception when params is empty
-   * @static
-   */
-  public static function add($params) {
-    $result = array();
-    if (empty($params)) {
-      throw new Exception('Params can not be empty when adding or updating a data processor source');
-    }
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::pre('edit', 'DataProcessorSource', $params['id'], $params);
-    }
-    else {
-      CRM_Utils_Hook::pre('create', 'DataProcessorSource', NULL, $params);
-    }
-
-    $source = new CRM_Dataprocessor_DAO_Source();
-    $fields = self::fields();
-    foreach ($params as $key => $value) {
-      if (isset($fields[$key])) {
-        $source->$key = $value;
-      }
-    }
-    if (isset($source->configuration) && is_array($source->configuration)) {
-      $source->configuration = json_encode($source->configuration);
-    }
-    if (isset($source->join_configuration) && is_array($source->join_configuration)) {
-      $source->join_configuration = json_encode($source->join_configuration);
-    }
-
-    $source->save();
-    $id = $source->id;
-    $source = new CRM_Dataprocessor_BAO_Source();
-    $source->id = $id;
-    $source->find(true);
-    CRM_Dataprocessor_BAO_DataProcessor::updateAndChekStatus($source->data_processor_id);
-    self::storeValues($source, $result);
-
-    if (!empty($params['id'])) {
-      CRM_Utils_Hook::post('edit', 'DataProcessorSource', $source->id, $source);
-    }
-    else {
-      CRM_Utils_Hook::post('create', 'DataProcessorSource', $source->id, $source);
-    }
-
-    return $result;
-  }
-
-  /**
-   * Public function to generate name from title
-   *
-   * @param $label
-   * @return string
-   * @access public
-   * @static
-   */
-  public static function buildNameFromTitle($title) {
-    return preg_replace('@[^a-z0-9_]+@','_', strtolower($title));
-  }
-
-  /**
-   * Returns whether the name is valid or not
-   *
-   * @param string $name
-   * @param int $data_procssor_id,
-   * @param int $id optional
-   * @return bool
-   * @static
-   */
-  public static function isNameValid($name, $data_procssor_id, $id=null) {
-    $sql = "SELECT COUNT(*) FROM `civicrm_data_processor_source` WHERE `name` = %1 AND `data_processor_id` = %2";
-    $params[1] = array($name, 'String');
-    $params[2] = array($data_procssor_id, 'Integer');
-    if ($id) {
-      $sql .= " AND `id` != %3";
-      $params[3] = array($id, 'Integer');
-    }
-    $count = CRM_Core_DAO::singleValueQuery($sql, $params);
-    return ($count > 0) ? false : true;
-  }
-
-  /**
-   * Function to delete a Data Processor Source with id
-   *
-   * @param int $id
-   * @throws Exception when $id is empty
-   * @access public
-   * @static
-   */
-  public static function deleteWithId($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to delete a data processor source');
-    }
-
-    CRM_Utils_Hook::pre('delete', 'DataProcessorSource', $id, CRM_Core_DAO::$_nullArray);
-
-    $source = new CRM_Dataprocessor_DAO_Source();
-    $source->id = $id;
-    $source->delete();
-
-    CRM_Utils_Hook::post('delete', 'DataProcessorSource', $id, CRM_Core_DAO::$_nullArray);
-
-    return;
-  }
-
-  /**
-   * Function to delete a Data Processor Source with id
-   *
-   * @param int $id
-   * @throws Exception when $id is empty
-   * @access public
-   * @static
-   */
-  public static function deleteWithDataProcessorId($id) {
-    if (empty($id)) {
-      throw new Exception('id can not be empty when attempting to delete a data processor source');
-    }
-
-    $source = new CRM_Dataprocessor_DAO_Source();
-    $source->data_processor_id = $id;
-    $source->find(FALSE);
-    while ($source->fetch()) {
-      self::deleteWithId($source->id);
-    }
-  }
-
-  /**
-   * @param $source
-   * @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor
-   * @return \Civi\DataProcessor\Source\SourceInterface
-   */
-  public static function getSourceClass($source, \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor) {
-    $factory = dataprocessor_get_factory();
-    $sourceClass = $factory->getDataSourceByName($source['type']);
-    $sourceClass->setSourceName($source['name']);
-    $sourceClass->setSourceTitle($source['title']);
-    $sourceClass->setConfiguration($source['configuration']);
-    $sourceClass->setDataProcessor($dataProcessor);
-    $join = null;
-    if ($source['join_type']) {
-      $join = $factory->getJoinByName($source['join_type']);
-      $join->setConfiguration($source['join_configuration']);
-      $join->setDataProcessor($dataProcessor);
-    }
-    $dataProcessor->addDataSource($sourceClass, $join);
-    if ($join) {
-      $join->initialize();
-      $sourceClass->setJoin($join);
-    }
-    return $sourceClass;
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/DAO/DataProcessor.php b/CRM/Dataprocessor/DAO/DataProcessor.php
index b21b9f076da5e00985c99e8f1c18703a11d25d18..cb6c049e427de40543ea85579090642318f00c58 100644
--- a/CRM/Dataprocessor/DAO/DataProcessor.php
+++ b/CRM/Dataprocessor/DAO/DataProcessor.php
@@ -1,137 +1,316 @@
 <?php
 
-use CRM_Dataprocessor_ExtensionUtil as E;
+/**
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2019
+ *
+ * Generated from /buildkit/build/search/sites/default/files/civicrm/ext/dataprocessor/xml/schema/CRM/Dataprocessor/DataProcessor.xml
+ * DO NOT EDIT.  Generated by CRM_Core_CodeGen
+ * (GenCodeChecksum:28cee8d17fc4e4fca4b21a0b4dbf17ff)
+ */
 
 /**
- * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org>
- * @license http://www.gnu.org/licenses/agpl-3.0.html
+ * Database access object for the DataProcessor entity.
  */
 class CRM_Dataprocessor_DAO_DataProcessor extends CRM_Core_DAO {
 
-  const STATUS_IN_DATABASE = 1;
-  const STATUS_IN_CODE = 2;
-  const STATUS_OVERRIDDEN = 3;
+  /**
+   * Static instance to hold the table name.
+   *
+   * @var string
+   */
+  static $_tableName = 'civicrm_data_processor';
+
+  /**
+   * Should CiviCRM log any modifications to this table in the civicrm_log table.
+   *
+   * @var bool
+   */
+  static $_log = FALSE;
 
   /**
-   * static instance to hold the field values
+   * Unique DataProcessor ID
    *
-   * @var array
-   * @static
+   * @var int unsigned
    */
-  static $_fields = null;
-  static $_export = null;
+  public $id;
+
   /**
-   * empty definition for virtual function
+   * @var string
    */
-  static function getTableName() {
-    return 'civicrm_data_processor';
+  public $name;
+
+  /**
+   * @var string
+   */
+  public $title;
+
+  /**
+   * @var string
+   */
+  public $type;
+
+  /**
+   * @var text
+   */
+  public $configuration;
+
+  /**
+   * @var text
+   */
+  public $aggregation;
+
+  /**
+   * @var boolean
+   */
+  public $is_active;
+
+  /**
+   * @var text
+   */
+  public $description;
+
+  /**
+   * @var string
+   */
+  public $storage_type;
+
+  /**
+   * @var text
+   */
+  public $storage_configuration;
+
+  /**
+   * @var int unsigned
+   */
+  public $status;
+
+  /**
+   * @var string
+   */
+  public $source_file;
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    $this->__table = 'civicrm_data_processor';
+    parent::__construct();
   }
+
   /**
-   * returns all the column names of this table
+   * Returns all the column names of this table
    *
-   * @access public
    * @return array
    */
   public static function &fields() {
-    if (!(self::$_fields)) {
-      self::$_fields = array(
-        'id' => array(
+    if (!isset(Civi::$statics[__CLASS__]['fields'])) {
+      Civi::$statics[__CLASS__]['fields'] = [
+        'id' => [
           'name' => 'id',
-          'title' => E::ts('ID'),
           'type' => CRM_Utils_Type::T_INT,
-          'required' => true
-        ) ,
-        'type' => array(
-          'name' => 'type',
-          'title' => E::ts('Type'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 80,
-          'required' => true,
-        ),
-        'name' => array(
+          'description' => CRM_Dataprocessor_ExtensionUtil::ts('Unique DataProcessor ID'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+        ],
+        'name' => [
           'name' => 'name',
-          'title' => E::ts('Name'),
           'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 128,
-          'required' => true
-        ),
-        'title' => array(
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Name'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+        ],
+        'title' => [
           'name' => 'title',
-          'title' => E::ts('Title'),
           'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 128,
-          'required' => true
-        ),
-        'is_active' => array(
-          'name' => 'is_active',
-          'title' => E::ts('Is active'),
-          'type' => CRM_Utils_Type::T_INT,
-        ),
-        'description' => array(
-          'name' => 'description',
-          'title' => E::ts('Description'),
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Title'),
+          'required' => TRUE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+        ],
+        'type' => [
+          'name' => 'type',
           'type' => CRM_Utils_Type::T_STRING,
-        ),
-        'configuration' => array(
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Type'),
+          'required' => TRUE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+        ],
+        'configuration' => [
           'name' => 'configuration',
-          'title' => E::ts('Configuration'),
           'type' => CRM_Utils_Type::T_TEXT,
-        ),
-        'aggregation' => array(
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Configuration'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+          'serialize' => self::SERIALIZE_JSON,
+        ],
+        'aggregation' => [
           'name' => 'aggregation',
-          'title' => E::ts('Aggregation'),
           'type' => CRM_Utils_Type::T_TEXT,
-        ),
-        'storage_type' => array(
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Aggregation Fields'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+          'serialize' => self::SERIALIZE_JSON,
+        ],
+        'is_active' => [
+          'name' => 'is_active',
+          'type' => CRM_Utils_Type::T_BOOLEAN,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Is active'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+        ],
+        'description' => [
+          'name' => 'description',
+          'type' => CRM_Utils_Type::T_TEXT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Description'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+        ],
+        'storage_type' => [
           'name' => 'storage_type',
-          'title' => E::ts('Storage Type'),
           'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 80,
-          'required' => true,
-        ),
-        'storage_configuration' => array(
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Storage Type'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+        ],
+        'storage_configuration' => [
           'name' => 'storage_configuration',
-          'title' => E::ts('Storage Configuration'),
           'type' => CRM_Utils_Type::T_TEXT,
-        ),
-        'status' => array(
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Storage Configuration'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+          'serialize' => self::SERIALIZE_JSON,
+        ],
+        'status' => [
           'name' => 'status',
           'type' => CRM_Utils_Type::T_INT,
-        ),
-        'source_file' => array(
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Status'),
+          'required' => FALSE,
+          'default' => '0',
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+        ],
+        'source_file' => [
           'name' => 'source_file',
-          'title' => E::ts('Source file'),
           'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Source File'),
+          'required' => FALSE,
           'maxlength' => 255,
-          'required' => false,
-        ),
-      );
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor',
+          'entity' => 'DataProcessor',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessor',
+          'localizable' => 0,
+        ],
+      ];
+      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
     }
-    return self::$_fields;
+    return Civi::$statics[__CLASS__]['fields'];
   }
+
   /**
-   * Returns an array containing, for each field, the array key used for that
-   * field in self::$_fields.
+   * Return a mapping from field-name to the corresponding key (as used in fields()).
    *
-   * @access public
    * @return array
+   *   Array(string $name => string $uniqueName).
    */
   public static function &fieldKeys() {
-    if (!(self::$_fieldKeys)) {
-      self::$_fieldKeys = array(
-        'id' => 'id',
-        'type' => 'type',
-        'name' => 'name',
-        'title' => 'title',
-        'is_active' => 'is_active',
-        'description' => 'description',
-        'configuration' => 'configuration',
-        'storage_type' => 'storage_type',
-        'storage_configuration' => 'storage_configuration',
-        'status' => 'status',
-        'source_file' => 'source_file',
-      );
+    if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
+      Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
     }
-    return self::$_fieldKeys;
+    return Civi::$statics[__CLASS__]['fieldKeys'];
+  }
+
+  /**
+   * Returns the names of this table
+   *
+   * @return string
+   */
+  public static function getTableName() {
+    return self::$_tableName;
+  }
+
+  /**
+   * Returns if this table needs to be logged
+   *
+   * @return bool
+   */
+  public function getLog() {
+    return self::$_log;
   }
-}
\ No newline at end of file
+
+  /**
+   * Returns the list of fields that can be imported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &import($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'data_processor', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of fields that can be exported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &export($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'data_processor', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of indices
+   *
+   * @param bool $localize
+   *
+   * @return array
+   */
+  public static function indices($localize = TRUE) {
+    $indices = [];
+    return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
+  }
+
+}
diff --git a/CRM/Dataprocessor/DAO/DataProcessorField.php b/CRM/Dataprocessor/DAO/DataProcessorField.php
new file mode 100644
index 0000000000000000000000000000000000000000..1818c0fbdb693e29a7431cbba0b95d2912de305b
--- /dev/null
+++ b/CRM/Dataprocessor/DAO/DataProcessorField.php
@@ -0,0 +1,252 @@
+<?php
+
+/**
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2019
+ *
+ * Generated from /buildkit/build/search/sites/default/files/civicrm/ext/dataprocessor/xml/schema/CRM/Dataprocessor/DataProcessorField.xml
+ * DO NOT EDIT.  Generated by CRM_Core_CodeGen
+ * (GenCodeChecksum:31241877b684b9293303c171b4a4dcbb)
+ */
+
+/**
+ * Database access object for the DataProcessorField entity.
+ */
+class CRM_Dataprocessor_DAO_DataProcessorField extends CRM_Core_DAO {
+
+  /**
+   * Static instance to hold the table name.
+   *
+   * @var string
+   */
+  static $_tableName = 'civicrm_data_processor_field';
+
+  /**
+   * Should CiviCRM log any modifications to this table in the civicrm_log table.
+   *
+   * @var bool
+   */
+  static $_log = FALSE;
+
+  /**
+   * Unique DataProcessorField ID
+   *
+   * @var int unsigned
+   */
+  public $id;
+
+  /**
+   * FK to Data Processor
+   *
+   * @var int unsigned
+   */
+  public $data_processor_id;
+
+  /**
+   * @var int
+   */
+  public $weight;
+
+  /**
+   * @var string
+   */
+  public $name;
+
+  /**
+   * @var string
+   */
+  public $title;
+
+  /**
+   * @var string
+   */
+  public $type;
+
+  /**
+   * @var text
+   */
+  public $configuration;
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    $this->__table = 'civicrm_data_processor_field';
+    parent::__construct();
+  }
+
+  /**
+   * Returns foreign keys and entity references.
+   *
+   * @return array
+   *   [CRM_Core_Reference_Interface]
+   */
+  public static function getReferenceColumns() {
+    if (!isset(Civi::$statics[__CLASS__]['links'])) {
+      Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
+      Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), 'data_processor_id', 'civicrm_data_processor', 'id');
+      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
+    }
+    return Civi::$statics[__CLASS__]['links'];
+  }
+
+  /**
+   * Returns all the column names of this table
+   *
+   * @return array
+   */
+  public static function &fields() {
+    if (!isset(Civi::$statics[__CLASS__]['fields'])) {
+      Civi::$statics[__CLASS__]['fields'] = [
+        'id' => [
+          'name' => 'id',
+          'type' => CRM_Utils_Type::T_INT,
+          'description' => CRM_Dataprocessor_ExtensionUtil::ts('Unique DataProcessorField ID'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor_field',
+          'entity' => 'DataProcessorField',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorField',
+          'localizable' => 0,
+        ],
+        'data_processor_id' => [
+          'name' => 'data_processor_id',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Data Processor ID'),
+          'description' => CRM_Dataprocessor_ExtensionUtil::ts('FK to Data Processor'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor_field',
+          'entity' => 'DataProcessorField',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorField',
+          'localizable' => 0,
+        ],
+        'weight' => [
+          'name' => 'weight',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Weight'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor_field',
+          'entity' => 'DataProcessorField',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorField',
+          'localizable' => 0,
+        ],
+        'name' => [
+          'name' => 'name',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Name'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_field',
+          'entity' => 'DataProcessorField',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorField',
+          'localizable' => 0,
+        ],
+        'title' => [
+          'name' => 'title',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Title'),
+          'required' => TRUE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_field',
+          'entity' => 'DataProcessorField',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorField',
+          'localizable' => 0,
+        ],
+        'type' => [
+          'name' => 'type',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Type'),
+          'required' => TRUE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_field',
+          'entity' => 'DataProcessorField',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorField',
+          'localizable' => 0,
+        ],
+        'configuration' => [
+          'name' => 'configuration',
+          'type' => CRM_Utils_Type::T_TEXT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Configuration'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor_field',
+          'entity' => 'DataProcessorField',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorField',
+          'localizable' => 0,
+          'serialize' => self::SERIALIZE_JSON,
+        ],
+      ];
+      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
+    }
+    return Civi::$statics[__CLASS__]['fields'];
+  }
+
+  /**
+   * Return a mapping from field-name to the corresponding key (as used in fields()).
+   *
+   * @return array
+   *   Array(string $name => string $uniqueName).
+   */
+  public static function &fieldKeys() {
+    if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
+      Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
+    }
+    return Civi::$statics[__CLASS__]['fieldKeys'];
+  }
+
+  /**
+   * Returns the names of this table
+   *
+   * @return string
+   */
+  public static function getTableName() {
+    return self::$_tableName;
+  }
+
+  /**
+   * Returns if this table needs to be logged
+   *
+   * @return bool
+   */
+  public function getLog() {
+    return self::$_log;
+  }
+
+  /**
+   * Returns the list of fields that can be imported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &import($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'data_processor_field', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of fields that can be exported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &export($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'data_processor_field', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of indices
+   *
+   * @param bool $localize
+   *
+   * @return array
+   */
+  public static function indices($localize = TRUE) {
+    $indices = [];
+    return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
+  }
+
+}
diff --git a/CRM/Dataprocessor/DAO/DataProcessorFilter.php b/CRM/Dataprocessor/DAO/DataProcessorFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a34a33c3f28bc751642f9aa0bd3cd733606d8b5
--- /dev/null
+++ b/CRM/Dataprocessor/DAO/DataProcessorFilter.php
@@ -0,0 +1,267 @@
+<?php
+
+/**
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2019
+ *
+ * Generated from /buildkit/build/search/sites/default/files/civicrm/ext/dataprocessor/xml/schema/CRM/Dataprocessor/DataProcessorFilter.xml
+ * DO NOT EDIT.  Generated by CRM_Core_CodeGen
+ * (GenCodeChecksum:a0b00b49eb3a0197adf06272fc6e31f7)
+ */
+
+/**
+ * Database access object for the DataProcessorFilter entity.
+ */
+class CRM_Dataprocessor_DAO_DataProcessorFilter extends CRM_Core_DAO {
+
+  /**
+   * Static instance to hold the table name.
+   *
+   * @var string
+   */
+  static $_tableName = 'civicrm_data_processor_filter';
+
+  /**
+   * Should CiviCRM log any modifications to this table in the civicrm_log table.
+   *
+   * @var bool
+   */
+  static $_log = FALSE;
+
+  /**
+   * Unique DataProcessorFilter ID
+   *
+   * @var int unsigned
+   */
+  public $id;
+
+  /**
+   * FK to Data Processor
+   *
+   * @var int unsigned
+   */
+  public $data_processor_id;
+
+  /**
+   * @var int
+   */
+  public $weight;
+
+  /**
+   * @var string
+   */
+  public $name;
+
+  /**
+   * @var string
+   */
+  public $title;
+
+  /**
+   * @var string
+   */
+  public $type;
+
+  /**
+   * @var boolean
+   */
+  public $is_required;
+
+  /**
+   * @var text
+   */
+  public $configuration;
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    $this->__table = 'civicrm_data_processor_filter';
+    parent::__construct();
+  }
+
+  /**
+   * Returns foreign keys and entity references.
+   *
+   * @return array
+   *   [CRM_Core_Reference_Interface]
+   */
+  public static function getReferenceColumns() {
+    if (!isset(Civi::$statics[__CLASS__]['links'])) {
+      Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
+      Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), 'data_processor_id', 'civicrm_data_processor', 'id');
+      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
+    }
+    return Civi::$statics[__CLASS__]['links'];
+  }
+
+  /**
+   * Returns all the column names of this table
+   *
+   * @return array
+   */
+  public static function &fields() {
+    if (!isset(Civi::$statics[__CLASS__]['fields'])) {
+      Civi::$statics[__CLASS__]['fields'] = [
+        'id' => [
+          'name' => 'id',
+          'type' => CRM_Utils_Type::T_INT,
+          'description' => CRM_Dataprocessor_ExtensionUtil::ts('Unique DataProcessorFilter ID'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor_filter',
+          'entity' => 'DataProcessorFilter',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+          'localizable' => 0,
+        ],
+        'data_processor_id' => [
+          'name' => 'data_processor_id',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Data Processor ID'),
+          'description' => CRM_Dataprocessor_ExtensionUtil::ts('FK to Data Processor'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor_filter',
+          'entity' => 'DataProcessorFilter',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+          'localizable' => 0,
+        ],
+        'weight' => [
+          'name' => 'weight',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Weight'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor_filter',
+          'entity' => 'DataProcessorFilter',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+          'localizable' => 0,
+        ],
+        'name' => [
+          'name' => 'name',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Name'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_filter',
+          'entity' => 'DataProcessorFilter',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+          'localizable' => 0,
+        ],
+        'title' => [
+          'name' => 'title',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Title'),
+          'required' => TRUE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_filter',
+          'entity' => 'DataProcessorFilter',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+          'localizable' => 0,
+        ],
+        'type' => [
+          'name' => 'type',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Type'),
+          'required' => TRUE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_filter',
+          'entity' => 'DataProcessorFilter',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+          'localizable' => 0,
+        ],
+        'is_required' => [
+          'name' => 'is_required',
+          'type' => CRM_Utils_Type::T_BOOLEAN,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Is required'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor_filter',
+          'entity' => 'DataProcessorFilter',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+          'localizable' => 0,
+        ],
+        'configuration' => [
+          'name' => 'configuration',
+          'type' => CRM_Utils_Type::T_TEXT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Configuration'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor_filter',
+          'entity' => 'DataProcessorFilter',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+          'localizable' => 0,
+          'serialize' => self::SERIALIZE_JSON,
+        ],
+      ];
+      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
+    }
+    return Civi::$statics[__CLASS__]['fields'];
+  }
+
+  /**
+   * Return a mapping from field-name to the corresponding key (as used in fields()).
+   *
+   * @return array
+   *   Array(string $name => string $uniqueName).
+   */
+  public static function &fieldKeys() {
+    if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
+      Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
+    }
+    return Civi::$statics[__CLASS__]['fieldKeys'];
+  }
+
+  /**
+   * Returns the names of this table
+   *
+   * @return string
+   */
+  public static function getTableName() {
+    return self::$_tableName;
+  }
+
+  /**
+   * Returns if this table needs to be logged
+   *
+   * @return bool
+   */
+  public function getLog() {
+    return self::$_log;
+  }
+
+  /**
+   * Returns the list of fields that can be imported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &import($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'data_processor_filter', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of fields that can be exported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &export($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'data_processor_filter', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of indices
+   *
+   * @param bool $localize
+   *
+   * @return array
+   */
+  public static function indices($localize = TRUE) {
+    $indices = [];
+    return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
+  }
+
+}
diff --git a/CRM/Dataprocessor/DAO/DataProcessorOutput.php b/CRM/Dataprocessor/DAO/DataProcessorOutput.php
new file mode 100644
index 0000000000000000000000000000000000000000..292d810ab4532ebe5a701c52c69c1fc60615655c
--- /dev/null
+++ b/CRM/Dataprocessor/DAO/DataProcessorOutput.php
@@ -0,0 +1,271 @@
+<?php
+
+/**
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2019
+ *
+ * Generated from /buildkit/build/search/sites/default/files/civicrm/ext/dataprocessor/xml/schema/CRM/Dataprocessor/DataProcessorOutput.xml
+ * DO NOT EDIT.  Generated by CRM_Core_CodeGen
+ * (GenCodeChecksum:f38dc40dc234990d0664637ae1b9a8d6)
+ */
+
+/**
+ * Database access object for the DataProcessorOutput entity.
+ */
+class CRM_Dataprocessor_DAO_DataProcessorOutput extends CRM_Core_DAO {
+
+  /**
+   * Static instance to hold the table name.
+   *
+   * @var string
+   */
+  static $_tableName = 'civicrm_data_processor_output';
+
+  /**
+   * Should CiviCRM log any modifications to this table in the civicrm_log table.
+   *
+   * @var bool
+   */
+  static $_log = FALSE;
+
+  /**
+   * Unique DataProcessorOutput ID
+   *
+   * @var int unsigned
+   */
+  public $id;
+
+  /**
+   * FK to Data Processor
+   *
+   * @var int unsigned
+   */
+  public $data_processor_id;
+
+  /**
+   * @var string
+   */
+  public $type;
+
+  /**
+   * @var text
+   */
+  public $configuration;
+
+  /**
+   * @var string
+   */
+  public $permission;
+
+  /**
+   * @var string
+   */
+  public $api_entity;
+
+  /**
+   * @var string
+   */
+  public $api_action;
+
+  /**
+   * @var string
+   */
+  public $api_count_action;
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    $this->__table = 'civicrm_data_processor_output';
+    parent::__construct();
+  }
+
+  /**
+   * Returns foreign keys and entity references.
+   *
+   * @return array
+   *   [CRM_Core_Reference_Interface]
+   */
+  public static function getReferenceColumns() {
+    if (!isset(Civi::$statics[__CLASS__]['links'])) {
+      Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
+      Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), 'data_processor_id', 'civicrm_data_processor', 'id');
+      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
+    }
+    return Civi::$statics[__CLASS__]['links'];
+  }
+
+  /**
+   * Returns all the column names of this table
+   *
+   * @return array
+   */
+  public static function &fields() {
+    if (!isset(Civi::$statics[__CLASS__]['fields'])) {
+      Civi::$statics[__CLASS__]['fields'] = [
+        'id' => [
+          'name' => 'id',
+          'type' => CRM_Utils_Type::T_INT,
+          'description' => CRM_Dataprocessor_ExtensionUtil::ts('Unique DataProcessorOutput ID'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor_output',
+          'entity' => 'DataProcessorOutput',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+          'localizable' => 0,
+        ],
+        'data_processor_id' => [
+          'name' => 'data_processor_id',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Data Processor ID'),
+          'description' => CRM_Dataprocessor_ExtensionUtil::ts('FK to Data Processor'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor_output',
+          'entity' => 'DataProcessorOutput',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+          'localizable' => 0,
+        ],
+        'type' => [
+          'name' => 'type',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Type'),
+          'required' => TRUE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_output',
+          'entity' => 'DataProcessorOutput',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+          'localizable' => 0,
+        ],
+        'configuration' => [
+          'name' => 'configuration',
+          'type' => CRM_Utils_Type::T_TEXT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Configuration'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor_output',
+          'entity' => 'DataProcessorOutput',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+          'localizable' => 0,
+          'serialize' => self::SERIALIZE_JSON,
+        ],
+        'permission' => [
+          'name' => 'permission',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Permission'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_output',
+          'entity' => 'DataProcessorOutput',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+          'localizable' => 0,
+        ],
+        'api_entity' => [
+          'name' => 'api_entity',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('API Entity'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_output',
+          'entity' => 'DataProcessorOutput',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+          'localizable' => 0,
+        ],
+        'api_action' => [
+          'name' => 'api_action',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('API Action'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_output',
+          'entity' => 'DataProcessorOutput',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+          'localizable' => 0,
+        ],
+        'api_count_action' => [
+          'name' => 'api_count_action',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('API Getcount action'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_output',
+          'entity' => 'DataProcessorOutput',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+          'localizable' => 0,
+        ],
+      ];
+      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
+    }
+    return Civi::$statics[__CLASS__]['fields'];
+  }
+
+  /**
+   * Return a mapping from field-name to the corresponding key (as used in fields()).
+   *
+   * @return array
+   *   Array(string $name => string $uniqueName).
+   */
+  public static function &fieldKeys() {
+    if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
+      Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
+    }
+    return Civi::$statics[__CLASS__]['fieldKeys'];
+  }
+
+  /**
+   * Returns the names of this table
+   *
+   * @return string
+   */
+  public static function getTableName() {
+    return self::$_tableName;
+  }
+
+  /**
+   * Returns if this table needs to be logged
+   *
+   * @return bool
+   */
+  public function getLog() {
+    return self::$_log;
+  }
+
+  /**
+   * Returns the list of fields that can be imported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &import($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'data_processor_output', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of fields that can be exported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &export($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'data_processor_output', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of indices
+   *
+   * @param bool $localize
+   *
+   * @return array
+   */
+  public static function indices($localize = TRUE) {
+    $indices = [];
+    return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
+  }
+
+}
diff --git a/CRM/Dataprocessor/DAO/DataProcessorSource.php b/CRM/Dataprocessor/DAO/DataProcessorSource.php
new file mode 100644
index 0000000000000000000000000000000000000000..c9c8251e8084ee35ff9edc4f804f1b1fdd6f2871
--- /dev/null
+++ b/CRM/Dataprocessor/DAO/DataProcessorSource.php
@@ -0,0 +1,285 @@
+<?php
+
+/**
+ * @package CRM
+ * @copyright CiviCRM LLC (c) 2004-2019
+ *
+ * Generated from /buildkit/build/search/sites/default/files/civicrm/ext/dataprocessor/xml/schema/CRM/Dataprocessor/DataProcessorSource.xml
+ * DO NOT EDIT.  Generated by CRM_Core_CodeGen
+ * (GenCodeChecksum:41ade3cbfbb5da57e4ce47f3580c7c36)
+ */
+
+/**
+ * Database access object for the DataProcessorSource entity.
+ */
+class CRM_Dataprocessor_DAO_DataProcessorSource extends CRM_Core_DAO {
+
+  /**
+   * Static instance to hold the table name.
+   *
+   * @var string
+   */
+  static $_tableName = 'civicrm_data_processor_source';
+
+  /**
+   * Should CiviCRM log any modifications to this table in the civicrm_log table.
+   *
+   * @var bool
+   */
+  static $_log = FALSE;
+
+  /**
+   * Unique DataProcessorSource ID
+   *
+   * @var int unsigned
+   */
+  public $id;
+
+  /**
+   * FK to Data Processor
+   *
+   * @var int unsigned
+   */
+  public $data_processor_id;
+
+  /**
+   * @var int
+   */
+  public $weight;
+
+  /**
+   * @var string
+   */
+  public $name;
+
+  /**
+   * @var string
+   */
+  public $title;
+
+  /**
+   * @var string
+   */
+  public $type;
+
+  /**
+   * @var text
+   */
+  public $configuration;
+
+  /**
+   * @var string
+   */
+  public $join_type;
+
+  /**
+   * @var text
+   */
+  public $join_configuration;
+
+  /**
+   * Class constructor.
+   */
+  public function __construct() {
+    $this->__table = 'civicrm_data_processor_source';
+    parent::__construct();
+  }
+
+  /**
+   * Returns foreign keys and entity references.
+   *
+   * @return array
+   *   [CRM_Core_Reference_Interface]
+   */
+  public static function getReferenceColumns() {
+    if (!isset(Civi::$statics[__CLASS__]['links'])) {
+      Civi::$statics[__CLASS__]['links'] = static ::createReferenceColumns(__CLASS__);
+      Civi::$statics[__CLASS__]['links'][] = new CRM_Core_Reference_Basic(self::getTableName(), 'data_processor_id', 'civicrm_data_processor', 'id');
+      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'links_callback', Civi::$statics[__CLASS__]['links']);
+    }
+    return Civi::$statics[__CLASS__]['links'];
+  }
+
+  /**
+   * Returns all the column names of this table
+   *
+   * @return array
+   */
+  public static function &fields() {
+    if (!isset(Civi::$statics[__CLASS__]['fields'])) {
+      Civi::$statics[__CLASS__]['fields'] = [
+        'id' => [
+          'name' => 'id',
+          'type' => CRM_Utils_Type::T_INT,
+          'description' => CRM_Dataprocessor_ExtensionUtil::ts('Unique DataProcessorSource ID'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor_source',
+          'entity' => 'DataProcessorSource',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+          'localizable' => 0,
+        ],
+        'data_processor_id' => [
+          'name' => 'data_processor_id',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Data Processor ID'),
+          'description' => CRM_Dataprocessor_ExtensionUtil::ts('FK to Data Processor'),
+          'required' => TRUE,
+          'table_name' => 'civicrm_data_processor_source',
+          'entity' => 'DataProcessorSource',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+          'localizable' => 0,
+        ],
+        'weight' => [
+          'name' => 'weight',
+          'type' => CRM_Utils_Type::T_INT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Weight'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor_source',
+          'entity' => 'DataProcessorSource',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+          'localizable' => 0,
+        ],
+        'name' => [
+          'name' => 'name',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Name'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_source',
+          'entity' => 'DataProcessorSource',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+          'localizable' => 0,
+        ],
+        'title' => [
+          'name' => 'title',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Title'),
+          'required' => TRUE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_source',
+          'entity' => 'DataProcessorSource',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+          'localizable' => 0,
+        ],
+        'type' => [
+          'name' => 'type',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Type'),
+          'required' => TRUE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_source',
+          'entity' => 'DataProcessorSource',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+          'localizable' => 0,
+        ],
+        'configuration' => [
+          'name' => 'configuration',
+          'type' => CRM_Utils_Type::T_TEXT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Configuration'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor_source',
+          'entity' => 'DataProcessorSource',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+          'localizable' => 0,
+          'serialize' => self::SERIALIZE_JSON,
+        ],
+        'join_type' => [
+          'name' => 'join_type',
+          'type' => CRM_Utils_Type::T_STRING,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Join Type'),
+          'required' => FALSE,
+          'maxlength' => 255,
+          'size' => CRM_Utils_Type::HUGE,
+          'table_name' => 'civicrm_data_processor_source',
+          'entity' => 'DataProcessorSource',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+          'localizable' => 0,
+        ],
+        'join_configuration' => [
+          'name' => 'join_configuration',
+          'type' => CRM_Utils_Type::T_TEXT,
+          'title' => CRM_Dataprocessor_ExtensionUtil::ts('Join Configuration'),
+          'required' => FALSE,
+          'table_name' => 'civicrm_data_processor_source',
+          'entity' => 'DataProcessorSource',
+          'bao' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+          'localizable' => 0,
+          'serialize' => self::SERIALIZE_JSON,
+        ],
+      ];
+      CRM_Core_DAO_AllCoreTables::invoke(__CLASS__, 'fields_callback', Civi::$statics[__CLASS__]['fields']);
+    }
+    return Civi::$statics[__CLASS__]['fields'];
+  }
+
+  /**
+   * Return a mapping from field-name to the corresponding key (as used in fields()).
+   *
+   * @return array
+   *   Array(string $name => string $uniqueName).
+   */
+  public static function &fieldKeys() {
+    if (!isset(Civi::$statics[__CLASS__]['fieldKeys'])) {
+      Civi::$statics[__CLASS__]['fieldKeys'] = array_flip(CRM_Utils_Array::collect('name', self::fields()));
+    }
+    return Civi::$statics[__CLASS__]['fieldKeys'];
+  }
+
+  /**
+   * Returns the names of this table
+   *
+   * @return string
+   */
+  public static function getTableName() {
+    return self::$_tableName;
+  }
+
+  /**
+   * Returns if this table needs to be logged
+   *
+   * @return bool
+   */
+  public function getLog() {
+    return self::$_log;
+  }
+
+  /**
+   * Returns the list of fields that can be imported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &import($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getImports(__CLASS__, 'data_processor_source', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of fields that can be exported
+   *
+   * @param bool $prefix
+   *
+   * @return array
+   */
+  public static function &export($prefix = FALSE) {
+    $r = CRM_Core_DAO_AllCoreTables::getExports(__CLASS__, 'data_processor_source', $prefix, []);
+    return $r;
+  }
+
+  /**
+   * Returns the list of indices
+   *
+   * @param bool $localize
+   *
+   * @return array
+   */
+  public static function indices($localize = TRUE) {
+    $indices = [];
+    return ($localize && !empty($indices)) ? CRM_Core_DAO_AllCoreTables::multilingualize(__CLASS__, $indices) : $indices;
+  }
+
+}
diff --git a/CRM/Dataprocessor/DAO/Field.php b/CRM/Dataprocessor/DAO/Field.php
deleted file mode 100644
index c9fcb770deaa45dfa128095fe963780a518f0dea..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/DAO/Field.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org>
- * @license http://www.gnu.org/licenses/agpl-3.0.html
- */
-class CRM_Dataprocessor_DAO_Field extends CRM_Core_DAO {
-  /**
-   * static instance to hold the field values
-   *
-   * @var array
-   * @static
-   */
-  static $_fields = null;
-  static $_export = null;
-  /**
-   * empty definition for virtual function
-   */
-  static function getTableName() {
-    return 'civicrm_data_processor_field';
-  }
-  /**
-   * returns all the column names of this table
-   *
-   * @access public
-   * @return array
-   */
-  public static function &fields() {
-    if (!(self::$_fields)) {
-      self::$_fields = array(
-        'id' => array(
-          'name' => 'id',
-          'title' => E::ts('ID'),
-          'type' => CRM_Utils_Type::T_INT,
-          'required' => true
-        ) ,
-        'weight' => array(
-          'name' => 'weight',
-          'title' => E::ts('Weight'),
-          'type' => CRM_Utils_Type::T_INT,
-          'required' => true
-        ) ,
-        'data_processor_id' => array(
-          'name' => 'data_processor_id',
-          'title' => E::ts('Data Processor ID'),
-          'type' => CRM_Utils_Type::T_INT,
-          'required' => true,
-          'FKApiName' => 'DataProcessor',
-        ),
-        'type' => array(
-          'name' => 'type',
-          'title' => E::ts('Type'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 80,
-          'required' => true,
-        ),
-        'name' => array(
-          'name' => 'name',
-          'title' => E::ts('Name'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 128,
-          'required' => true
-        ),
-        'title' => array(
-          'name' => 'title',
-          'title' => E::ts('Title'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 128,
-          'required' => true
-        ),
-        'configuration' => array(
-          'name' => 'configuration',
-          'title' => E::ts('Configuration'),
-          'type' => CRM_Utils_Type::T_TEXT,
-        ),
-      );
-    }
-    return self::$_fields;
-  }
-  /**
-   * Returns an array containing, for each field, the array key used for that
-   * field in self::$_fields.
-   *
-   * @access public
-   * @return array
-   */
-  public static function &fieldKeys() {
-    if (!(self::$_fieldKeys)) {
-      self::$_fieldKeys = array(
-        'id' => 'id',
-        'weight' => 'weight',
-        'data_processor_id' => 'data_processor_id',
-        'type' => 'type',
-        'name' => 'name',
-        'title' => 'title',
-        'configuration' => 'configuration',
-      );
-    }
-    return self::$_fieldKeys;
-  }
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/DAO/Filter.php b/CRM/Dataprocessor/DAO/Filter.php
deleted file mode 100644
index 6be51fceaff8de35076466a95625863e8c83cf82..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/DAO/Filter.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org>
- * @license http://www.gnu.org/licenses/agpl-3.0.html
- */
-class CRM_Dataprocessor_DAO_Filter extends CRM_Core_DAO {
-  /**
-   * static instance to hold the field values
-   *
-   * @var array
-   * @static
-   */
-  static $_fields = null;
-  static $_export = null;
-  /**
-   * empty definition for virtual function
-   */
-  static function getTableName() {
-    return 'civicrm_data_processor_filter';
-  }
-  /**
-   * returns all the column names of this table
-   *
-   * @access public
-   * @return array
-   */
-  public static function &fields() {
-    if (!(self::$_fields)) {
-      self::$_fields = array(
-        'id' => array(
-          'name' => 'id',
-          'title' => E::ts('ID'),
-          'type' => CRM_Utils_Type::T_INT,
-          'required' => true
-        ) ,
-        'data_processor_id' => array(
-          'name' => 'data_processor_id',
-          'title' => E::ts('Data Processor ID'),
-          'type' => CRM_Utils_Type::T_INT,
-          'required' => true,
-          'FKApiName' => 'DataProcessor',
-        ),
-        'is_required' => array(
-          'name' => 'is_required',
-          'title' => E::ts('Is required'),
-          'type' => CRM_Utils_Type::T_INT,
-        ),
-        'type' => array(
-          'name' => 'type',
-          'title' => E::ts('Type'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 80,
-          'required' => true,
-        ),
-        'name' => array(
-          'name' => 'name',
-          'title' => E::ts('Name'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 128,
-          'required' => true
-        ),
-        'title' => array(
-          'name' => 'title',
-          'title' => E::ts('Title'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 128,
-          'required' => true
-        ),
-        'configuration' => array(
-          'name' => 'configuration',
-          'title' => E::ts('Configuration'),
-          'type' => CRM_Utils_Type::T_TEXT,
-        ),
-      );
-    }
-    return self::$_fields;
-  }
-  /**
-   * Returns an array containing, for each field, the array key used for that
-   * field in self::$_fields.
-   *
-   * @access public
-   * @return array
-   */
-  public static function &fieldKeys() {
-    if (!(self::$_fieldKeys)) {
-      self::$_fieldKeys = array(
-        'id' => 'id',
-        'data_processor_id' => 'data_processor_id',
-        'is_required' => 'is_required',
-        'type' => 'type',
-        'name' => 'name',
-        'title' => 'title',
-        'configuration' => 'configuration',
-      );
-    }
-    return self::$_fieldKeys;
-  }
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/DAO/Output.php b/CRM/Dataprocessor/DAO/Output.php
deleted file mode 100644
index f1da9d5511ca4fd1a5488f1eecb24e6a689b957e..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/DAO/Output.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org>
- * @license http://www.gnu.org/licenses/agpl-3.0.html
- */
-class CRM_Dataprocessor_DAO_Output extends CRM_Core_DAO {
-  /**
-   * static instance to hold the field values
-   *
-   * @var array
-   * @static
-   */
-  static $_fields = null;
-  static $_export = null;
-  /**
-   * empty definition for virtual function
-   */
-  static function getTableName() {
-    return 'civicrm_data_processor_output';
-  }
-  /**
-   * returns all the column names of this table
-   *
-   * @access public
-   * @return array
-   */
-  public static function &fields() {
-    if (!(self::$_fields)) {
-      self::$_fields = array(
-        'id' => array(
-          'name' => 'id',
-          'title' => E::ts('ID'),
-          'type' => CRM_Utils_Type::T_INT,
-          'required' => true
-        ) ,
-        'data_processor_id' => array(
-          'name' => 'data_processor_id',
-          'title' => E::ts('Data Processor ID'),
-          'type' => CRM_Utils_Type::T_INT,
-          'required' => true,
-          'FKApiName' => 'DataProcessor',
-        ),
-        'type' => array(
-          'name' => 'type',
-          'title' => E::ts('Type'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 80,
-          'required' => true,
-        ),
-        'configuration' => array(
-          'name' => 'configuration',
-          'title' => E::ts('Configuration'),
-          'type' => CRM_Utils_Type::T_TEXT,
-        ),
-        'permission' => array(
-          'name' => 'permission',
-          'title' => E::ts('Permission'),
-          'type' => CRM_Utils_Type::T_STRING
-        ),
-        'api_entity' => array(
-          'name' => 'api_entity',
-          'title' => E::ts('API Entity'),
-          'type' => CRM_Utils_Type::T_STRING
-        ),
-        'api_action' => array(
-          'name' => 'api_action',
-          'title' => E::ts('API Action Name'),
-          'type' => CRM_Utils_Type::T_STRING
-        ),
-        'api_count_action' => array(
-          'name' => 'api_count_action',
-          'title' => E::ts('API GetCount Action Name'),
-          'type' => CRM_Utils_Type::T_STRING
-        ),
-      );
-    }
-    return self::$_fields;
-  }
-  /**
-   * Returns an array containing, for each field, the array key used for that
-   * field in self::$_fields.
-   *
-   * @access public
-   * @return array
-   */
-  public static function &fieldKeys() {
-    if (!(self::$_fieldKeys)) {
-      self::$_fieldKeys = array(
-        'id' => 'id',
-        'data_processor_id' => 'data_processor_id',
-        'type' => 'type',
-        'configuration' => 'configuration',
-      );
-    }
-    return self::$_fieldKeys;
-  }
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/DAO/Source.php b/CRM/Dataprocessor/DAO/Source.php
deleted file mode 100644
index f2579a3ce76b357a134118e6eb46cd64ac211290..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/DAO/Source.php
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * @author Jaap Jansma (CiviCooP) <jaap.jansma@civicoop.org>
- * @license http://www.gnu.org/licenses/agpl-3.0.html
- */
-class CRM_Dataprocessor_DAO_Source extends CRM_Core_DAO {
-  /**
-   * static instance to hold the field values
-   *
-   * @var array
-   * @static
-   */
-  static $_fields = null;
-  static $_export = null;
-  /**
-   * empty definition for virtual function
-   */
-  static function getTableName() {
-    return 'civicrm_data_processor_source';
-  }
-  /**
-   * returns all the column names of this table
-   *
-   * @access public
-   * @return array
-   */
-  public static function &fields() {
-    if (!(self::$_fields)) {
-      self::$_fields = array(
-        'id' => array(
-          'name' => 'id',
-          'title' => E::ts('ID'),
-          'type' => CRM_Utils_Type::T_INT,
-          'required' => true
-        ) ,
-        'data_processor_id' => array(
-          'name' => 'data_processor_id',
-          'title' => E::ts('Data Processor ID'),
-          'type' => CRM_Utils_Type::T_INT,
-          'required' => true,
-          'FKApiName' => 'DataProcessor',
-        ),
-        'type' => array(
-          'name' => 'type',
-          'title' => E::ts('Type'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 80,
-          'required' => true,
-        ),
-        'name' => array(
-          'name' => 'name',
-          'title' => E::ts('Name'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 128,
-          'required' => true
-        ),
-        'title' => array(
-          'name' => 'title',
-          'title' => E::ts('Title'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 128,
-          'required' => true
-        ),
-        'configuration' => array(
-          'name' => 'configuration',
-          'title' => E::ts('Configuration'),
-          'type' => CRM_Utils_Type::T_TEXT,
-        ),
-        'join_type' => array(
-          'name' => 'join_type',
-          'title' => E::ts('Join Type'),
-          'type' => CRM_Utils_Type::T_STRING,
-          'maxlength' => 80,
-          'required' => true,
-        ),
-        'join_configuration' => array(
-          'name' => 'join_configuration',
-          'title' => E::ts('Join Configuration'),
-          'type' => CRM_Utils_Type::T_TEXT,
-        ),
-      );
-    }
-    return self::$_fields;
-  }
-  /**
-   * Returns an array containing, for each field, the array key used for that
-   * field in self::$_fields.
-   *
-   * @access public
-   * @return array
-   */
-  public static function &fieldKeys() {
-    if (!(self::$_fieldKeys)) {
-      self::$_fieldKeys = array(
-        'id' => 'id',
-        'data_processor_id' => 'data_processor_id',
-        'type' => 'type',
-        'name' => 'name',
-        'title' => 'title',
-        'configuration' => 'configuration',
-        'join_type' => 'join_type',
-        'join_configuration' => 'join_configuration',
-      );
-    }
-    return self::$_fieldKeys;
-  }
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/AggregateField.php b/CRM/Dataprocessor/Form/AggregateField.php
index 2658c9c40029fec36d366c788c586319851e6630..07afcefb21dca2bd7caaaccb27951a9d76290cd9 100644
--- a/CRM/Dataprocessor/Form/AggregateField.php
+++ b/CRM/Dataprocessor/Form/AggregateField.php
@@ -11,6 +11,8 @@ class CRM_Dataprocessor_Form_AggregateField extends CRM_Core_Form {
 
   private $dataProcessorId;
 
+  private $dataProcessor;
+
   private $id;
 
   /**
@@ -19,28 +21,31 @@ class CRM_Dataprocessor_Form_AggregateField extends CRM_Core_Form {
    * @access public
    */
   function preProcess() {
-    $session = CRM_Core_Session::singleton();
     $this->dataProcessorId = CRM_Utils_Request::retrieve('id', 'Integer');
+    $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $this->dataProcessorId));
+    $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor);
     $this->assign('data_processor_id', $this->dataProcessorId);
 
     $title = E::ts('Data Processor Field');
     CRM_Utils_System::setTitle($title);
-
-    $url = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('id' => $this->dataProcessorId, 'action' => 'update', 'reset' => 1));
-    $session->pushUserContext($url);
   }
 
   public function buildQuickForm() {
     $this->add('hidden', 'id');
     $this->add('hidden', 'alias');
     if ($this->_action != CRM_Core_Action::DELETE) {
-      $fields = CRM_Dataprocessor_BAO_DataProcessor::getAvailableAggregationFields($this->dataProcessorId);
-      $fieldSelect = array(E::ts('- Select -'));
-      foreach($fields as $field) {
-        $fieldSelect[$field->fieldSpecification->alias] = $field->dataSource->getSourceTitle()." :: ".$field->fieldSpecification->title;
+      $aggregationFieldsFormatted = array();
+      foreach($this->dataProcessorClass->getDataSources() as $dataSource) {
+        foreach($dataSource->getAvailableAggregationFields() as $field) {
+          $aggregationFieldsFormatted[$field->fieldSpecification->alias] = $field->dataSource->getSourceTitle()." :: ".$field->fieldSpecification->title;
+        }
       }
 
-      $this->add('select', 'field', E::ts('Select Field'), $fieldSelect, true, array('class' => 'crm-select2 crm-huge40'));
+      $this->add('select', 'field', E::ts('Select Field'), $aggregationFieldsFormatted, true, array(
+        'style' => 'min-width:250px',
+        'class' => 'crm-select2 huge',
+        'placeholder' => E::ts('- select -'),
+      ));
     }
     if ($this->_action == CRM_Core_Action::ADD) {
       $this->addButtons(array(
@@ -63,31 +68,29 @@ class CRM_Dataprocessor_Form_AggregateField extends CRM_Core_Form {
 
   public function postProcess() {
     $session = CRM_Core_Session::singleton();
-    $redirectUrl = $session->readUserContext();
+    $redirectUrl = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('reset' => 1, 'action' => 'update', 'id' => $this->dataProcessorId));
     if ($this->_action == CRM_Core_Action::DELETE) {
       $values = $this->exportValues();
-      $dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getValues(array('id' => $this->dataProcessorId));
-      $aggregation = $dataProcessor[$this->dataProcessorId]['aggregation'];
-      $dataProcessor[$this->dataProcessorId]['aggregation'] = array();
+      $aggregation = $this->dataProcessor['aggregation'];
+      $this->dataProcessor['aggregation'] = array();
       foreach($aggregation as $alias) {
         if ($alias != $values['alias']) {
-          $dataProcessor[$this->dataProcessorId]['aggregation'][] = $alias;
+          $this->dataProcessor['aggregation'][] = $alias;
         }
       }
-      $result = CRM_Dataprocessor_BAO_DataProcessor::add($dataProcessor[$this->dataProcessorId]);
+      $result = civicrm_api3('DataProcessor', 'create', $this->dataProcessor);
 
       $session->setStatus(E::ts('Field removed'), E::ts('Removed'), 'success');
       CRM_Utils_System::redirect($redirectUrl);
     }
 
     $values = $this->exportValues();
-    $dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getValues(array('id' => $this->dataProcessorId));
-    $aggregation = $dataProcessor[$this->dataProcessorId]['aggregation'];
+    $aggregation = $this->dataProcessor['aggregation'];
     if (!in_array($values['field'], $aggregation)) {
       $aggregation[] = $values['field'];
     }
-    $dataProcessor[$this->dataProcessorId]['aggregation'] = $aggregation;
-    $result = CRM_Dataprocessor_BAO_DataProcessor::add($dataProcessor[$this->dataProcessorId]);
+    $this->dataProcessor['aggregation'] = $aggregation;
+    $result = civicrm_api3('DataProcessor', 'create', $this->dataProcessor);
 
     CRM_Utils_System::redirect($redirectUrl);
     parent::postProcess();
diff --git a/CRM/Dataprocessor/Form/DataProcessor.php b/CRM/Dataprocessor/Form/DataProcessor.php
index abe5155f21f07630df68328bdece550f9ae2c2df..eaa2cf8d67e23332f44703415b99446b6f398725 100644
--- a/CRM/Dataprocessor/Form/DataProcessor.php
+++ b/CRM/Dataprocessor/Form/DataProcessor.php
@@ -11,6 +11,13 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
 
   private $dataProcessorId;
 
+  private $dataProcessor;
+
+  /**
+   * @var \Civi\DataProcessor\ProcessorType\AbstractProcessorType
+   */
+  private $dataProcessorClass;
+
   private $currentUrl;
 
   /**
@@ -26,12 +33,12 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
     $session = CRM_Core_Session::singleton();
     switch($this->_action) {
       case CRM_Core_Action::DISABLE:
-        CRM_Dataprocessor_BAO_DataProcessor::disable($this->dataProcessorId);
+        civicrm_api3('DataProcessor', 'create', array('id' => $this->dataProcessorId, 'is_active' => 0));
         $session->setStatus('Data Processor disabled', 'Disable', 'success');
         CRM_Utils_System::redirect($session->readUserContext());
         break;
       case CRM_Core_Action::ENABLE:
-        CRM_Dataprocessor_BAO_DataProcessor::enable($this->dataProcessorId);
+        civicrm_api3('DataProcessor', 'create', array('id' => $this->dataProcessorId, 'is_active' => 1));
         $session->setStatus('Data Processor enabled', 'Enable', 'success');
         CRM_Utils_System::redirect($session->readUserContext());
         break;
@@ -41,11 +48,14 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
         CRM_Utils_System::redirect($session->readUserContext());
         break;
       case CRM_Core_Action::EXPORT:
-        $this->assign('export', json_encode(CRM_Dataprocessor_BAO_DataProcessor::export($this->dataProcessorId), JSON_PRETTY_PRINT));
+        $this->assign('export', json_encode(CRM_Dataprocessor_Utils_Importer::export($this->dataProcessorId), JSON_PRETTY_PRINT));
         break;
     }
 
     if ($this->dataProcessorId) {
+      $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $this->dataProcessorId));
+      $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor);
+      $this->assign('dataProcessor', $this->dataProcessor);
       $this->addSources();
       $this->addFields();
       $this->addFilters();
@@ -66,49 +76,43 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
 
   protected function addSources() {
     $factory = dataprocessor_get_factory();
-    $sources = CRM_Dataprocessor_BAO_Source::getValues(array('data_processor_id' => $this->dataProcessorId));
+    $types = $factory->getDataSources();
+    $sources = civicrm_api3('DataProcessorSource', 'get', array('data_processor_id' => $this->dataProcessorId, 'options' => array('limit' => 0)));
+    $sources = $sources['values'];
+    CRM_Utils_Weight::addOrder($sources, 'CRM_Dataprocessor_DAO_DataProcessorSource', 'id', $this->currentUrl, 'data_processor_id='.$this->dataProcessorId);
     foreach($sources as $idx => $source) {
-      $sources[$idx]['join_link'] = '';
-      if (isset($source['join_type']) && $source['join_type']) {
-        $joinClass = $factory->getJoinByName($source['join_type']);
-        $sources[$idx]['join_link'] = CRM_Utils_System::url($joinClass->getConfigurationUrl(), array('reset' => 1, 'source_id' => $source['id'], 'data_processor_id' => $this->dataProcessorId));
-      }
-      $sources[$idx]['configuration_link'] = '';
-      $sourceClass = $factory->getDataSourceByName($source['type']);
-      if ($sourceClass->getConfigurationUrl()) {
-        $sources[$idx]['configuration_link'] = CRM_Utils_System::url($sourceClass->getConfigurationUrl(), array('reset' => 1, 'source_id' => $source['id'], 'data_processor_id' => $this->dataProcessorId));
+      if (isset($types[$source['type']])) {
+        $sources[$idx]['type_name'] = $types[$source['type']];
+      } else {
+        $sources[$idx]['type_name'] = '';
       }
     }
     $this->assign('sources', $sources);
   }
 
   protected function addFields() {
-    $fields = CRM_Dataprocessor_BAO_Field::getValues(array('data_processor_id' => $this->dataProcessorId));
-    foreach($fields as $idx => $field) {
-      $fields[$idx]['configuration_link'] = '';
-    }
-    CRM_Utils_Weight::addOrder($fields, 'CRM_Dataprocessor_DAO_Field', 'id', $this->currentUrl, 'data_processor_id='.$this->dataProcessorId);
+    $fields = civicrm_api3('DataProcessorField', 'get', array('data_processor_id' => $this->dataProcessorId, 'options' => array('limit' => 0)));
+    $fields = $fields['values'];
+    CRM_Utils_Weight::addOrder($fields, 'CRM_Dataprocessor_DAO_DataProcessorField', 'id', $this->currentUrl, 'data_processor_id='.$this->dataProcessorId);
     $this->assign('fields', $fields);
   }
 
   protected function addFilters() {
-    $filters = CRM_Dataprocessor_BAO_Filter::getValues(array('data_processor_id' => $this->dataProcessorId));
-    foreach($filters as $idx => $filter) {
-      $filters[$idx]['is_required'] = $filter['is_required'] ? E::ts('Yes') : E::ts('No');
-      $filters[$idx]['configuration_link'] = '';
-    }
+    $filters = civicrm_api3('DataProcessorFilter', 'get', array('data_processor_id' => $this->dataProcessorId, 'options' => array('limit' => 0)));
+    $filters = $filters['values'];
+    CRM_Utils_Weight::addOrder($filters, 'CRM_Dataprocessor_DAO_DataProcessorFilter', 'id', $this->currentUrl, 'data_processor_id='.$this->dataProcessorId);
     $this->assign('filters', $filters);
   }
 
   protected function addAggregateFields() {
-    $fields = array();
-    $aggregationFields = CRM_Dataprocessor_BAO_DataProcessor::getAvailableAggregationFields($this->dataProcessorId);
     $aggregationFieldsFormatted = array();
-    foreach($aggregationFields as $field) {
-      $aggregationFieldsFormatted[$field->fieldSpecification->alias] = $field->dataSource->getSourceTitle()." :: ".$field->fieldSpecification->title;
+    foreach($this->dataProcessorClass->getDataSources() as $dataSource) {
+      foreach($dataSource->getAvailableAggregationFields() as $field) {
+        $aggregationFieldsFormatted[$field->fieldSpecification->alias] = $field->dataSource->getSourceTitle()." :: ".$field->fieldSpecification->title;
+      }
     }
-    $dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getValues(array('id' => $this->dataProcessorId));
-    $aggregation = $dataProcessor[$this->dataProcessorId]['aggregation'];
+    $aggregation = $this->dataProcessor['aggregation'];
+    $fields = array();
     foreach($aggregation as $alias) {
       $fields[$alias] = $aggregationFieldsFormatted[$alias];
     }
@@ -117,18 +121,16 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
 
   protected function addOutputs() {
     $factory = dataprocessor_get_factory();
-    $outputs = CRM_Dataprocessor_BAO_Output::getValues(array('data_processor_id' => $this->dataProcessorId));
+    $types = $factory->getOutputs();
+    $outputs = civicrm_api3('DataProcessorOutput', 'get', array('data_processor_id' => $this->dataProcessorId, 'options' => array('limit' => 0)));
+    $outputs = $outputs['values'];
     foreach($outputs as $idx => $output) {
-      $outputs[$idx]['configuration_link'] = '';
-      $outputClass  = $factory->getOutputByName($output['type']);
-      if  ($outputClass->getConfigurationUrl()) {
-        $outputs[$idx]['configuration_link'] = CRM_Utils_System::url($outputClass->getConfigurationUrl(), [
-          'reset' => 1,
-          'action' =>  'update',
-          'id' => $output['id'],
-          'data_processor_id' => $this->dataProcessorId
-        ]);
+      if (isset($types[$output['type']])) {
+        $outputs[$idx]['type_name'] = $types[$output['type']];
+      } else {
+        $outputs[$idx]['type_name'] = '';
       }
+      $outputs[$idx]['configuration_link'] = '';
     }
     $this->assign('outputs', $outputs);
   }
@@ -184,7 +186,7 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
   public function postProcess() {
     $session = CRM_Core_Session::singleton();
     if ($this->_action == CRM_Core_Action::DELETE) {
-      CRM_Dataprocessor_BAO_DataProcessor::deleteWithId($this->dataProcessorId);
+      civicrm_api3('DataProcessor', 'delete', array('id' => $this->dataProcessorId));
       $session->setStatus(E::ts('Data Processor removed'), E::ts('Removed'), 'success');
       $redirectUrl = $session->popUserContext();
       CRM_Utils_System::redirect($redirectUrl);
@@ -199,7 +201,8 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
       $params['id'] = $this->dataProcessorId;
     }
 
-    $result = CRM_Dataprocessor_BAO_DataProcessor::add($params);
+    $result = civicrm_api3('DataProcessor', 'create', $params);
+
     $redirectUrl = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('reset' => 1, 'action' => 'update', 'id' => $result['id']));
     CRM_Utils_System::redirect($redirectUrl);
   }
@@ -235,18 +238,17 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
    * @access protected
    */
   protected function setUpdateDefaults(&$defaults) {
-    $dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getValues(array('id' => $this->dataProcessorId));
-    if (!empty($dataProcessor) && !empty($this->dataProcessorId)) {
-      $defaults['title'] = $dataProcessor[$this->dataProcessorId]['title'];
-      if (isset($dataProcessor[$this->dataProcessorId]['name'])) {
-        $defaults['name'] = $dataProcessor[$this->dataProcessorId]['name'];
+    if (!empty($this->dataProcessor) && !empty($this->dataProcessorId)) {
+      $defaults['title'] = $this->dataProcessor['title'];
+      if (isset($this->dataProcessor['name'])) {
+        $defaults['name'] = $this->dataProcessor['name'];
       }
-      if (isset($dataProcessor[$this->dataProcessorId]['description'])) {
-        $defaults['description'] = $dataProcessor[$this->dataProcessorId]['description'];
+      if (isset($this->dataProcessor['description'])) {
+        $defaults['description'] = $this->dataProcessor['description'];
       } else {
         $defaults['description'] = '';
       }
-      $defaults['is_active'] = $dataProcessor[$this->dataProcessorId]['is_active'];
+      $defaults['is_active'] = $this->dataProcessor['is_active'];
     }
   }
 
@@ -266,7 +268,7 @@ class CRM_Dataprocessor_Form_DataProcessor extends CRM_Core_Form {
       $id = $fields['id'];
     }
     if (empty($fields['name'])) {
-      $fields['name'] = CRM_Dataprocessor_BAO_DataProcessor::buildNameFromTitle($fields['title']);
+      $fields['name'] = CRM_Dataprocessor_BAO_DataProcessor::checkName($fields['title'], $id);
     }
     if (!CRM_Dataprocessor_BAO_DataProcessor::isNameValid($fields['name'], $id)) {
       $errors['name'] = E::ts('There is already a data processor with this name');
diff --git a/CRM/Dataprocessor/Form/Field.php b/CRM/Dataprocessor/Form/Field.php
index 09a873aa845bddda0d6b32131eeb658ba568878c..fec0b4fa178277fd36a0db2c82c47914923f7cb9 100644
--- a/CRM/Dataprocessor/Form/Field.php
+++ b/CRM/Dataprocessor/Form/Field.php
@@ -11,31 +11,40 @@ class CRM_Dataprocessor_Form_Field extends CRM_Core_Form {
 
   private $dataProcessorId;
 
+  private $dataProcessor;
+
+  /**
+   * @var Civi\DataProcessor\ProcessorType\AbstractProcessorType
+   */
+  private $dataProcessorClass;
+
   private $id;
 
+  private $field;
+
   /**
    * Function to perform processing before displaying form (overrides parent function)
    *
    * @access public
    */
   function preProcess() {
-    $session = CRM_Core_Session::singleton();
     $this->dataProcessorId = CRM_Utils_Request::retrieve('data_processor_id', 'Integer');
     $this->assign('data_processor_id', $this->dataProcessorId);
+    if ($this->dataProcessorId) {
+      $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $this->dataProcessorId));
+      $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor);
+    }
 
     $this->id = CRM_Utils_Request::retrieve('id', 'Integer');
     $this->assign('id', $this->id);
 
     if ($this->id) {
-      $field = CRM_Dataprocessor_BAO_Field::getValues(array('id' => $this->id));
-      $this->assign('field', $field[$this->id]);
+      $this->field = civicrm_api3('DataProcessorField', 'getsingle', array('id' => $this->id));
+      $this->assign('field', $this->field);
     }
 
     $title = E::ts('Data Processor Field');
     CRM_Utils_System::setTitle($title);
-
-    $url = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('id' => $this->dataProcessorId, 'action' => 'update', 'reset' => 1));
-    $session->pushUserContext($url);
   }
 
   public function buildQuickForm() {
@@ -45,7 +54,7 @@ class CRM_Dataprocessor_Form_Field extends CRM_Core_Form {
       $this->add('text', 'name', E::ts('Name'), array('size' => CRM_Utils_Type::HUGE), FALSE);
       $this->add('text', 'title', E::ts('Title'), array('size' => CRM_Utils_Type::HUGE), TRUE);
 
-      $outputHandlers = CRM_Dataprocessor_BAO_DataProcessor::getAvailableOutputHandlers($this->dataProcessorId);
+      $outputHandlers = $this->dataProcessorClass->getAvailableOutputHandlers();
       foreach($outputHandlers as $outputHandler) {
         $outputHandlersSelect[$outputHandler->getName()] = $outputHandler->getTitle();
       }
@@ -77,24 +86,25 @@ class CRM_Dataprocessor_Form_Field extends CRM_Core_Form {
     $defaults['data_processor_id'] = $this->dataProcessorId;
     $defaults['id'] = $this->id;
 
-    $field = CRM_Dataprocessor_BAO_Field::getValues(array('id' => $this->id));
-    if (isset($field[$this->id]['type'])) {
-      $defaults['type'] = $field[$this->id]['type'];
-    }
-    if (isset($field[$this->id]['title'])) {
-      $defaults['title'] = $field[$this->id]['title'];
-    }
-    if (isset($field[$this->id]['name'])) {
-      $defaults['name'] = $field[$this->id]['name'];
+    if ($this->field) {
+      if (isset($this->field['type'])) {
+        $defaults['type'] = $this->field['type'];
+      }
+      if (isset($this->field['title'])) {
+        $defaults['title'] = $this->field['title'];
+      }
+      if (isset($this->field['name'])) {
+        $defaults['name'] = $this->field['name'];
+      }
     }
     return $defaults;
   }
 
   public function postProcess() {
     $session = CRM_Core_Session::singleton();
-    $redirectUrl = $session->readUserContext();
+    $redirectUrl = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('reset' => 1, 'action' => 'update', 'id' => $this->dataProcessorId));
     if ($this->_action == CRM_Core_Action::DELETE) {
-      CRM_Dataprocessor_BAO_Field::deleteWithId($this->id);
+      civicrm_api3('DataProcessorField', 'delete', array('id' => $this->id));
       $session->setStatus(E::ts('Field removed'), E::ts('Removed'), 'success');
       CRM_Utils_System::redirect($redirectUrl);
     }
@@ -102,61 +112,18 @@ class CRM_Dataprocessor_Form_Field extends CRM_Core_Form {
     $values = $this->exportValues();
     if (!empty($values['name'])) {
       $params['name'] = $values['name'];
-    } else {
-      $params['name'] = CRM_Dataprocessor_BAO_Field::buildNameFromTitle($values['title']);
     }
     $params['title'] = $values['title'];
     $params['type'] = $values['type'];
-    if ($this->dataProcessorId) {
-      $params['data_processor_id'] = $this->dataProcessorId;
-    }
+    $params['data_processor_id'] = $this->dataProcessorId;
     if ($this->id) {
       $params['id'] = $this->id;
     }
 
-    $result = CRM_Dataprocessor_BAO_Field::add($params);
+    civicrm_api3('DataProcessorField', 'create', $params);
 
     CRM_Utils_System::redirect($redirectUrl);
     parent::postProcess();
   }
 
-  /**
-   * Function to add validation rules (overrides parent function)
-   *
-   * @access public
-   */
-  function addRules() {
-    if ($this->_action != CRM_Core_Action::DELETE) {
-      $this->addFormRule(array(
-        'CRM_Dataprocessor_Form_Field',
-        'validateName'
-      ));
-    }
-  }
-
-  /**
-   * Function to validate if rule label already exists
-   *
-   * @param array $fields
-   * @return array|bool
-   * @access static
-   */
-  static function validateName($fields) {
-    /*
-     * if id not empty, edit mode. Check if changed before check if exists
-     */
-    $id = false;
-    if (!empty($fields['id'])) {
-      $id = $fields['id'];
-    }
-    if (empty($fields['name'])) {
-      $fields['name'] = CRM_Dataprocessor_BAO_Field::buildNameFromTitle($fields['title']);
-    }
-    if (!CRM_Dataprocessor_BAO_Field::isNameValid($fields['name'], $fields['data_processor_id'], $id)) {
-      $errors['name'] = E::ts('There is already a field with this name');
-      return $errors;
-    }
-    return TRUE;
-  }
-
 }
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Filter.php b/CRM/Dataprocessor/Form/Filter.php
index 04b249274fe261ba9bc3874a2ac00218dd581b5e..4dfd83bebba1af5a6ef67346988b32aa2bd4a611 100644
--- a/CRM/Dataprocessor/Form/Filter.php
+++ b/CRM/Dataprocessor/Form/Filter.php
@@ -13,52 +13,78 @@ class CRM_Dataprocessor_Form_Filter extends CRM_Core_Form {
 
   private $id;
 
+  private $filter;
+
+  /**
+   * @var Civi\DataProcessor\FilterHandler\AbstractFilterHandler
+   */
+  private $filterTypeClass;
+
+  private $snippet;
+
   /**
    * Function to perform processing before displaying form (overrides parent function)
    *
    * @access public
    */
   function preProcess() {
-    $session = CRM_Core_Session::singleton();
+    $this->snippet = CRM_Utils_Request::retrieve('snippet', 'String');
+    if ($this->snippet) {
+      $this->assign('suppressForm', TRUE);
+      $this->controller->_generateQFKey = FALSE;
+    }
+
+    $factory = dataprocessor_get_factory();
     $this->dataProcessorId = CRM_Utils_Request::retrieve('data_processor_id', 'Integer');
     $this->assign('data_processor_id', $this->dataProcessorId);
 
     $this->id = CRM_Utils_Request::retrieve('id', 'Integer');
     $this->assign('id', $this->id);
 
+    $this->assign('has_configuration', false);
     if ($this->id) {
-      $filter = CRM_Dataprocessor_BAO_Filter::getValues(array('id' => $this->id));
-      $this->assign('filter', $filter[$this->id]);
+      $this->filter = civicrm_api3('DataProcessorFilter', 'getsingle', array('id' => $this->id));
+      $this->assign('filter', $this->filter);
+      $this->filterTypeClass = $factory->getFilterByName($this->filter['type']);
+      $this->assign('has_configuration', $this->filterTypeClass->hasConfiguration());
+    }
+
+    $type = CRM_Utils_Request::retrieve('type', 'String');
+    if ($type) {
+      $this->filterTypeClass = $factory->getFilterByName($type);
+      $this->assign('has_configuration', $this->filterTypeClass->hasConfiguration());
+    }
+
+    if (!$this->filter) {
+      $this->filter['data_processor_id'] = $this->dataProcessorId;
     }
 
     $title = E::ts('Data Processor Filter');
     CRM_Utils_System::setTitle($title);
-
-    $url = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('id' => $this->dataProcessorId, 'action' => 'update', 'reset' => 1));
-    $session->pushUserContext($url);
   }
 
   public function buildQuickForm() {
     $this->add('hidden', 'data_processor_id');
     $this->add('hidden', 'id');
-    if ($this->_action != CRM_Core_Action::DELETE) {
+    if ($this->_action == CRM_Core_Action::DELETE) {
+      $this->addButtons(array(
+        array('type' => 'next', 'name' => E::ts('Delete'), 'isDefault' => TRUE,),
+        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
+    } else {
       $this->add('text', 'name', E::ts('Name'), array('size' => CRM_Utils_Type::HUGE), FALSE);
       $this->add('text', 'title', E::ts('Title'), array('size' => CRM_Utils_Type::HUGE), TRUE);
 
       $factory = dataprocessor_get_factory();
-      $filters = array(E::ts(' - select - '))  + $factory->getFilters();
-      $this->add('select', 'type', E::ts('Select Filter'), $filters, true, array('class' => 'crm-select2 crm-huge40'));
+      $this->add('select', 'type', E::ts('Select Filter'), $factory->getFilters(), true, array('style' => 'min-width:250px',
+        'class' => 'crm-select2 huge',
+        'placeholder' => E::ts('- select -'),));
       $this->add('checkbox', 'is_required', E::ts('Is required'));
-    }
-    if ($this->_action == CRM_Core_Action::ADD) {
-      $this->addButtons(array(
-        array('type' => 'next', 'name' => E::ts('Next'), 'isDefault' => TRUE,),
-        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
-    } elseif ($this->_action == CRM_Core_Action::DELETE) {
-      $this->addButtons(array(
-        array('type' => 'next', 'name' => E::ts('Delete'), 'isDefault' => TRUE,),
-        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
-    } else {
+
+      if ($this->filterTypeClass && $this->filterTypeClass->hasConfiguration()) {
+        $this->filterTypeClass->buildConfigurationForm($this, $this->filter);
+        $this->assign('configuration_template', $this->filterTypeClass->getConfigurationTemplateFileName());
+      }
+
       $this->addButtons(array(
         array('type' => 'next', 'name' => E::ts('Save'), 'isDefault' => TRUE,),
         array('type' => 'cancel', 'name' => E::ts('Cancel'))));
@@ -71,27 +97,30 @@ class CRM_Dataprocessor_Form_Filter extends CRM_Core_Form {
     $defaults['data_processor_id'] = $this->dataProcessorId;
     $defaults['id'] = $this->id;
 
-    $filter = CRM_Dataprocessor_BAO_Filter::getValues(array('id' => $this->id));
-    if (isset($filter[$this->id]['type'])) {
-      $defaults['type'] = $filter[$this->id]['type'];
+    if (isset($this->filter['type'])) {
+      $defaults['type'] = $this->filter['type'];
+    } else {
+      $factory = dataprocessor_get_factory();
+      $filter_types = array_keys($factory->getFilters());
+      $defaults['type'] = reset($filter_types);
     }
-    if (isset($filter[$this->id]['is_required'])) {
-      $defaults['is_required'] = $filter[$this->id]['is_required'];
+    if (isset($this->filter['is_required'])) {
+      $defaults['is_required'] = $this->filter['is_required'];
     }
-    if (isset($filter[$this->id]['title'])) {
-      $defaults['title'] = $filter[$this->id]['title'];
+    if (isset($this->filter['title'])) {
+      $defaults['title'] = $this->filter['title'];
     }
-    if (isset($filter[$this->id]['name'])) {
-      $defaults['name'] = $filter[$this->id]['name'];
+    if (isset($this->filter['name'])) {
+      $defaults['name'] = $this->filter['name'];
     }
     return $defaults;
   }
 
   public function postProcess() {
     $session = CRM_Core_Session::singleton();
-    $redirectUrl = $session->readUserContext();
+    $redirectUrl = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('reset' => 1, 'action' => 'update', 'id' => $this->dataProcessorId));
     if ($this->_action == CRM_Core_Action::DELETE) {
-      CRM_Dataprocessor_BAO_Filter::deleteWithId($this->id);
+      civicrm_api3('DataProcessorFilter', 'delete', array('id' => $this->id));
       $session->setStatus(E::ts('Filter removed'), E::ts('Removed'), 'success');
       CRM_Utils_System::redirect($redirectUrl);
     }
@@ -99,8 +128,6 @@ class CRM_Dataprocessor_Form_Filter extends CRM_Core_Form {
     $values = $this->exportValues();
     if (!empty($values['name'])) {
       $params['name'] = $values['name'];
-    } else {
-      $params['name'] = CRM_Dataprocessor_BAO_Filter::buildNameFromTitle($values['title']);
     }
     $params['title'] = $values['title'];
     $params['type'] = $values['type'];
@@ -112,59 +139,14 @@ class CRM_Dataprocessor_Form_Filter extends CRM_Core_Form {
       $params['id'] = $this->id;
     }
 
-    $result = CRM_Dataprocessor_BAO_Filter::add($params);
-    $factory = dataprocessor_get_factory();
-    $filter  = $factory->getFilterByName($values['type']);
-    if  ($filter->getConfigurationUrl($result['id'], $this->dataProcessorId)) {
-      $redirectUrl = CRM_Utils_System::url($filter->getConfigurationUrl(), [
-        'reset' => 1,
-        'action' =>  'update',
-        'id' => $result['id'],
-        'data_processor_id' => $this->dataProcessorId
-      ]);
+    if ($this->filterTypeClass && $this->filterTypeClass->hasConfiguration()) {
+      $params['configuration'] = $this->filterTypeClass->processConfiguration($values);
     }
 
+    civicrm_api3('DataProcessorFilter', 'create', $params);
+
     CRM_Utils_System::redirect($redirectUrl);
     parent::postProcess();
   }
 
-  /**
-   * Function to add validation rules (overrides parent function)
-   *
-   * @access public
-   */
-  function addRules() {
-    if ($this->_action != CRM_Core_Action::DELETE) {
-      $this->addFormRule(array(
-        'CRM_Dataprocessor_Form_Filter',
-        'validateName'
-      ));
-    }
-  }
-
-  /**
-   * Function to validate if rule label already exists
-   *
-   * @param array $fields
-   * @return array|bool
-   * @access static
-   */
-  static function validateName($fields) {
-    /*
-     * if id not empty, edit mode. Check if changed before check if exists
-     */
-    $id = false;
-    if (!empty($fields['id'])) {
-      $id = $fields['id'];
-    }
-    if (empty($fields['name'])) {
-      $fields['name'] = CRM_Dataprocessor_BAO_Filter::buildNameFromTitle($fields['title']);
-    }
-    if (!CRM_Dataprocessor_BAO_Filter::isNameValid($fields['name'], $fields['data_processor_id'], $id)) {
-      $errors['name'] = E::ts('There is already a filter with this name');
-      return $errors;
-    }
-    return TRUE;
-  }
-
 }
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Filter/AbstractFilterForm.php b/CRM/Dataprocessor/Form/Filter/AbstractFilterForm.php
deleted file mode 100644
index 95e3013bcb6a8763beded48bbe204d8eee60171f..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/Form/Filter/AbstractFilterForm.php
+++ /dev/null
@@ -1,139 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * Form controller class
- *
- * This class could be used as a base for other form classes.
- *
- * @see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference
- */
-abstract class CRM_Dataprocessor_Form_Filter_AbstractFilterForm extends CRM_Core_Form {
-
-  protected $dataProcessorId;
-
-  protected $id;
-
-  /**
-   * Function to perform processing before displaying form (overrides parent function)
-   *
-   * @access public
-   */
-  function preProcess() {
-    $session = CRM_Core_Session::singleton();
-    $this->dataProcessorId = CRM_Utils_Request::retrieve('data_processor_id', 'Integer');
-    $this->assign('data_processor_id', $this->dataProcessorId);
-
-    $this->id = CRM_Utils_Request::retrieve('id', 'Integer');
-    $this->assign('id', $this->id);
-
-    if ($this->id) {
-      $fiilter = CRM_Dataprocessor_BAO_Filter::getValues(array('id' => $this->id));
-      $this->assign('field', $fiilter[$this->id]);
-    }
-
-    $title = E::ts('Data Processor  Filter  Configuration');
-    CRM_Utils_System::setTitle($title);
-
-    $url = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('id' => $this->dataProcessorId, 'action' => 'update', 'reset' => 1));
-    $session->pushUserContext($url);
-  }
-
-  public function buildQuickForm() {
-    $this->add('hidden', 'data_processor_id');
-    $this->add('hidden', 'id');
-
-    $this->addButtons(array(
-      array('type' => 'next', 'name' => E::ts('Save'), 'isDefault' => TRUE,),
-      array('type' => 'cancel', 'name' => E::ts('Cancel')))
-    );
-    parent::buildQuickForm();
-  }
-
-  /**
-   * Add a select for the field selection
-   *
-   * @throws \Exception
-   */
-  protected function addFieldSelect($label) {
-    $fieldSelect = $this->getFieldOptions();
-
-    $this->add('select', 'field', $label, $fieldSelect, true, array(
-      'style' => 'min-width:250px',
-      'class' => 'crm-select2 huge',
-      'placeholder' => E::ts('- select -'),
-    ));
-  }
-
-  /**
-   * Returns an array with the name of the field as the key and the label of the field as the value.
-   *
-   * @return array
-   * @throws \Exception
-   */
-  protected function getFieldOptions() {
-    $dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getDataProcessorById($this->dataProcessorId);
-    foreach($dataProcessor->getDataSources() as $dataSource) {
-      foreach($dataSource->getAvailableFilterFields()->getFields() as $field) {
-        $fieldSelect[$dataSource->getSourceName().'::'.$field->name] = $dataSource->getSourceTitle().' :: '.$field->title;
-      }
-    }
-    return $fieldSelect;
-  }
-
-  function setDefaultValues() {
-    $defaults = [];
-    $defaults['data_processor_id'] = $this->dataProcessorId;
-    $defaults['id'] = $this->id;
-
-    return $defaults;
-  }
-
-  /**
-   * Set default values for field
-   *
-   * @param $defaults
-   *
-   * @return mixed
-   */
-  protected function getDefaultValuesForField($defaults) {
-    $filter = CRM_Dataprocessor_BAO_Filter::getValues(array('id' => $this->id));
-    if (isset($filter[$this->id]['configuration'])) {
-      $configuration = $filter[$this->id]['configuration'];
-      if (isset($configuration['datasource']) && isset($configuration['field'])) {
-        $defaults['field'] = $configuration['datasource'].'::'.$configuration['field'];
-      }
-    }
-    return $defaults;
-  }
-
-  /**
-   * Get the field configuration from the submitted Values
-   * @param $configuration
-   *
-   * @return mixed
-   */
-  protected function getFieldConfigurationFromSubmittedValues($configuration) {
-    $values = $this->exportValues();
-    list($datasource, $field) = explode('::', $values['field'], 2);
-    $configuration['field'] = $field;
-    $configuration['datasource'] = $datasource;
-    return $configuration;
-  }
-
-  /**
-   * Save the configuration
-   *
-   * @param $configuration
-   *
-   * @throws \Exception
-   */
-  protected function saveConfiguration($configuration) {
-    $filters = CRM_Dataprocessor_BAO_Filter::getValues(array('id' => $this->id));
-    $params = $filters[$this->id];
-    $params['configuration'] = $configuration;
-    $result = CRM_Dataprocessor_BAO_Filter::add($params);
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Filter/SimpleFilter.php b/CRM/Dataprocessor/Form/Filter/SimpleFilter.php
deleted file mode 100644
index 487ca65188dcf17d549e7fe51b48e23f86b3ed50..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/Form/Filter/SimpleFilter.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * Form controller class
- *
- * @see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference
- */
-class CRM_Dataprocessor_Form_Filter_SimpleFilter extends CRM_Dataprocessor_Form_Filter_AbstractFilterForm {
-
-
-  public function buildQuickForm() {
-    parent::buildQuickForm();
-    $this->addFieldSelect(E::ts('Select Field'));
-  }
-
-  function setDefaultValues() {
-    $defaults = parent::setDefaultValues();
-    $defaults = $this->getDefaultValuesForField($defaults);
-    return $defaults;
-  }
-
-  public function postProcess() {
-    $session = CRM_Core_Session::singleton();
-    $redirectUrl = $session->readUserContext();
-
-    $configuration = array();
-    $configuration = $this->getFieldConfigurationFromSubmittedValues($configuration);
-    $this->saveConfiguration($configuration);
-
-    CRM_Utils_System::redirect($redirectUrl);
-    parent::postProcess();
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Import.php b/CRM/Dataprocessor/Form/Import.php
index 039c4d50bb9517b902bbfe43917a2b6ddf992c5d..54d39d3d34b4053921e6cb5ca151c6ee409debdf 100644
--- a/CRM/Dataprocessor/Form/Import.php
+++ b/CRM/Dataprocessor/Form/Import.php
@@ -29,7 +29,7 @@ class CRM_Dataprocessor_Form_Import extends CRM_Core_Form {
   public function postProcess() {
     $values = $this->exportValues();
     $importCode = json_decode($values['code'], true);
-    $importResult = CRM_Dataprocessor_Utils_Importer::import($importCode, '');
+    $importResult = CRM_Dataprocessor_Utils_Importer::import($importCode, '', true);
 
     CRM_Core_Session::setStatus(E::ts('Imported data processor'), '', 'success');
 
diff --git a/CRM/Dataprocessor/Form/Join/Simple.php b/CRM/Dataprocessor/Form/Join/Simple.php
deleted file mode 100644
index e4c4d0c99f0dd1139ec99a57062c0e4ee7dc91e0..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/Form/Join/Simple.php
+++ /dev/null
@@ -1,130 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * Form controller class
- *
- * @see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference
- */
-class CRM_Dataprocessor_Form_Join_Simple extends CRM_Core_Form {
-
-  private $dataProcessorId;
-
-  private $source_id;
-
-  /**
-   * Function to perform processing before displaying form (overrides parent function)
-   *
-   * @access public
-   */
-  function preProcess() {
-    $this->dataProcessorId = CRM_Utils_Request::retrieve('data_processor_id', 'Integer');
-    $this->assign('data_processor_id', $this->dataProcessorId);
-
-    $this->source_id = CRM_Utils_Request::retrieve('source_id', 'Integer', CRM_Core_DAO::$_nullObject, TRUE);
-    $this->assign('source_id', $this->source_id);
-
-    $source = CRM_Dataprocessor_BAO_Source::getValues(array('id' => $this->source_id));
-    $this->assign('source', $source[$this->source_id]);
-
-    $title = E::ts('Data Processor Source Join Conifuration');
-    CRM_Utils_System::setTitle($title);
-  }
-
-  public function buildQuickForm() {
-    $this->add('hidden', 'data_processor_id');
-    $this->add('hidden', 'source_id');
-
-    $fields = $this->buildFieldList();
-
-    $this->add('select', 'left_field', ts('Select field'), $fields, true, array(
-      'style' => 'min-width:250px',
-      'class' => 'crm-select2 huge',
-      'placeholder' => E::ts('- select -'),
-    ));
-    $this->add('select', 'right_field', ts('Select field'), $fields, true, array(
-      'style' => 'min-width:250px',
-      'class' => 'crm-select2 huge',
-      'placeholder' => E::ts('- select -'),
-    ));
-
-    if ($this->_action == CRM_Core_Action::ADD) {
-      $this->addButtons(array(
-        array('type' => 'next', 'name' => E::ts('Next'), 'isDefault' => TRUE,),
-        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
-    } elseif ($this->_action == CRM_Core_Action::DELETE) {
-      $this->addButtons(array(
-        array('type' => 'next', 'name' => E::ts('Delete'), 'isDefault' => TRUE,),
-        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
-    } else {
-      $this->addButtons(array(
-        array('type' => 'next', 'name' => E::ts('Save'), 'isDefault' => TRUE,),
-        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
-    }
-    parent::buildQuickForm();
-  }
-
-  function setDefaultValues() {
-    $defaults = [];
-    $defaults['data_processor_id'] = $this->dataProcessorId;
-    $defaults['source_id'] = $this->source_id;
-
-    $source = CRM_Dataprocessor_BAO_Source::getValues(array('id' => $this->source_id));
-    if (isset($source[$this->source_id]['join_configuration']['left_prefix'])) {
-      $defaults['left_field'] = $source[$this->source_id]['join_configuration']['left_prefix'].".".$source[$this->source_id]['join_configuration']['left_field'];
-    }
-    if (isset($source[$this->source_id]['join_configuration']['right_prefix'])) {
-      $defaults['right_field'] = $source[$this->source_id]['join_configuration']['right_prefix'].".".$source[$this->source_id]['join_configuration']['right_field'];
-    }
-
-    return $defaults;
-  }
-
-  public function postProcess() {
-    $session = CRM_Core_Session::singleton();
-
-    $values = $this->exportValues();
-    list($left_prefix, $left_field) = explode(".",$values['left_field'], 2);
-    list($right_prefix, $right_field) = explode(".",$values['right_field'], 2);
-
-    $params['join_configuration'] = array(
-      'left_prefix' => $left_prefix,
-      'left_field' => $left_field,
-      'right_prefix' => $right_prefix,
-      'right_field' => $right_field
-    );
-    if ($this->dataProcessorId) {
-      $params['data_processor_id'] = $this->dataProcessorId;
-    }
-    if ($this->source_id) {
-      $params['id'] = $this->source_id;
-    }
-    CRM_Dataprocessor_BAO_Source::add($params);
-    CRM_Utils_System::redirect($session->readUserContext());
-    parent::postProcess();
-  }
-
-  function buildFieldList() {
-    $factory = dataprocessor_get_factory();
-    $fields = array();
-    $dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getDataProcessorById($this->dataProcessorId);
-    $sources = CRM_Dataprocessor_BAO_Source::getValues(array('data_processor_id' => $this->dataProcessorId));
-    foreach($sources as $source) {
-      $sourceClass = $factory->getDataSourceByName($source['type']);
-      $sourceClass->setDataProcessor($dataProcessor);
-      $sourceClass->initialize($source['configuration'], $source['name']);
-      $sourceFields = $sourceClass->getAvailableFields()->getFields();
-      foreach($sourceFields as $sourceField) {
-        $fields[$source['name'] . '.' . $sourceField->name] = $source['title'] . ' :: ' . $sourceField->title;
-      }
-
-      if ($source['id'] == $this->source_id) {
-        break;
-      }
-    }
-    asort($fields);
-    return $fields;
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/ManageDataProcessors.php b/CRM/Dataprocessor/Form/ManageDataProcessors.php
index f03174ec62c45cb4e1aee24eea9184390eb21f46..5d5c8c7ccee63692b8d46507777ad22327a95bca 100644
--- a/CRM/Dataprocessor/Form/ManageDataProcessors.php
+++ b/CRM/Dataprocessor/Form/ManageDataProcessors.php
@@ -15,38 +15,24 @@ class CRM_Dataprocessor_Form_ManageDataProcessors extends CRM_Core_Form {
 
     $this->setTitle(E::ts('Manage Data Processors'));
 
-    $whereClauses = array("1");
+    $apiParams = array();
     if (isset($formValues['title']) && !empty($formValues['title'])) {
-      $whereClauses[] = "`title` LIKE '%". CRM_Utils_Type::escape($formValues['title'], 'String')."%'";
+      $apiParams['title']['LIKE'] = $formValues['title'];
     }
     if (isset($formValues['description']) && !empty($formValues['description'])) {
-      $whereClauses[]  = "`description` LIKE '%". CRM_Utils_Type::escape($formValues['description'], 'String')."%'";
+      $apiParams['description']['LIKE'] = $formValues['description'];
     }
     if (isset($formValues['is_active']) && $formValues['is_active'] == '0') {
-      $whereClauses[] = "`is_active` = 0";
+      $apiParams['is_active'] = 0;
     } elseif (isset($formValues['is_active']) && $formValues['is_active'] == '1') {
-      $whereClauses[] = "`is_active` = 1";
+      $apiParams['is_active'] = 1;
     }
+    $apiParams['options']['limit'] = 0;
+    $dataProcessors = civicrm_api3('DataProcessor', 'get', $apiParams);
+    $dataProcessors = $dataProcessors['values'];
 
-    $whereStatement = implode(" AND ", $whereClauses);
-    $sql = "SELECT * FROM civicrm_data_processor WHERE {$whereStatement} ORDER BY is_active, title";
-    $dataProcessors = array();
-    $dao = CRM_Core_DAO::executeQuery($sql, array(), false, 'CRM_Dataprocessor_DAO_DataProcessor');
-    while($dao->fetch()) {
-      $row = array();
-      CRM_Dataprocessor_DAO_DataProcessor::storeValues($dao, $row);
-      switch ($row['status']) {
-        case CRM_Dataprocessor_DAO_DataProcessor::STATUS_IN_CODE:
-          $row['status_label'] = E::ts('In code');
-          break;
-        case CRM_Dataprocessor_DAO_DataProcessor::STATUS_OVERRIDDEN:
-          $row['status_label'] = E::ts('Overridden');
-          break;
-        case CRM_Dataprocessor_DAO_DataProcessor::STATUS_IN_DATABASE:
-          $row['status_label'] = E::ts('In database');
-          break;
-      }
-      $dataProcessors[] = $row;
+    foreach($dataProcessors as $idx => $dataProcessor) {
+      $dataProcessors[$idx]['status_label'] = CRM_Dataprocessor_Status::statusToLabel($dataProcessor['status']);
     }
     $this->assign('data_processors', $dataProcessors);
 
diff --git a/CRM/Dataprocessor/Form/Output.php b/CRM/Dataprocessor/Form/Output.php
index 7b57ab4d44da95a29f6ad71008134d2f3bd9326c..65ebeb6084a0b905828bc3376011e7b180b6e25a 100644
--- a/CRM/Dataprocessor/Form/Output.php
+++ b/CRM/Dataprocessor/Form/Output.php
@@ -13,13 +13,28 @@ class CRM_Dataprocessor_Form_Output extends CRM_Core_Form {
 
   private $id;
 
+  private $output;
+
+  /**
+   * @var Civi\DataProcessor\Output\OutputInterface
+   */
+  private $outputTypeClass;
+
+  private $snippet;
+
   /**
    * Function to perform processing before displaying form (overrides parent function)
    *
    * @access public
    */
   function preProcess() {
-    $session = CRM_Core_Session::singleton();
+    $this->snippet = CRM_Utils_Request::retrieve('snippet', 'String');
+    if ($this->snippet) {
+      $this->assign('suppressForm', TRUE);
+      $this->controller->_generateQFKey = FALSE;
+    }
+
+    $factory = dataprocessor_get_factory();
     $this->dataProcessorId = CRM_Utils_Request::retrieve('data_processor_id', 'Integer');
     $this->assign('data_processor_id', $this->dataProcessorId);
 
@@ -27,34 +42,43 @@ class CRM_Dataprocessor_Form_Output extends CRM_Core_Form {
     $this->assign('id', $this->id);
 
     if ($this->id) {
-      $output = CRM_Dataprocessor_BAO_Output::getValues(array('id' => $this->id));
-      $this->assign('output', $output[$this->id]);
+      $this->output = civicrm_api3('DataProcessorOutput', 'getsingle', array('id' => $this->id));
+      $this->assign('output', $this->output);
+      $this->outputTypeClass = $factory->getOutputByName($this->output['type']);
+      $this->assign('has_configuration', $this->outputTypeClass->hasConfiguration());
+    }
+
+    $type = CRM_Utils_Request::retrieve('type', 'String');
+    if ($type) {
+      $this->outputTypeClass = $factory->getOutputByName($type);
+      $this->assign('has_configuration', $this->outputTypeClass->hasConfiguration());
+    }
+
+    if (!$this->output) {
+      $this->output['data_processor_id'] = $this->dataProcessorId;
     }
 
     $title = E::ts('Data Processor Output');
     CRM_Utils_System::setTitle($title);
-
-    $url = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('id' => $this->dataProcessorId, 'action' => 'update', 'reset' => 1));
-    $session->pushUserContext($url);
   }
 
   public function buildQuickForm() {
     $this->add('hidden', 'data_processor_id');
     $this->add('hidden', 'id');
-    if ($this->_action != CRM_Core_Action::DELETE) {
-      $factory = dataprocessor_get_factory();
-      $types = array(' - select - ')  + $factory->getOutputs();
-      $this->add('select', 'type', ts('Select output'), $types, true, array('class' => 'crm-select2'));
-    }
-    if ($this->_action == CRM_Core_Action::ADD) {
-      $this->addButtons(array(
-        array('type' => 'next', 'name' => E::ts('Next'), 'isDefault' => TRUE,),
-        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
-    } elseif ($this->_action == CRM_Core_Action::DELETE) {
+    if ($this->_action == CRM_Core_Action::DELETE) {
       $this->addButtons(array(
         array('type' => 'next', 'name' => E::ts('Delete'), 'isDefault' => TRUE,),
         array('type' => 'cancel', 'name' => E::ts('Cancel'))));
     } else {
+      $factory = dataprocessor_get_factory();
+      $types = array(' - select - ')  + $factory->getOutputs();
+      $this->add('select', 'type', ts('Select output'), $types, true, array('class' => 'crm-select2'));
+
+      if ($this->outputTypeClass && $this->outputTypeClass->hasConfiguration()) {
+        $this->outputTypeClass->buildConfigurationForm($this, $this->output);
+        $this->assign('configuration_template', $this->outputTypeClass->getConfigurationTemplateFileName());
+      }
+
       $this->addButtons(array(
         array('type' => 'next', 'name' => E::ts('Save'), 'isDefault' => TRUE,),
         array('type' => 'cancel', 'name' => E::ts('Cancel'))));
@@ -67,18 +91,17 @@ class CRM_Dataprocessor_Form_Output extends CRM_Core_Form {
     $defaults['data_processor_id'] = $this->dataProcessorId;
     $defaults['id'] = $this->id;
 
-    $output = CRM_Dataprocessor_BAO_Output::getValues(array('id' => $this->id));
-    if (isset($output[$this->id]['type'])) {
-      $defaults['type'] = $output[$this->id]['type'];
+    if (isset($this->output['type'])) {
+      $defaults['type'] = $this->output['type'];
     }
     return $defaults;
   }
 
   public function postProcess() {
     $session = CRM_Core_Session::singleton();
-    $redirectUrl = $session->readUserContext();
+    $redirectUrl = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('reset' => 1, 'action' => 'update', 'id' => $this->dataProcessorId));
     if ($this->_action == CRM_Core_Action::DELETE) {
-      CRM_Dataprocessor_BAO_Output::deleteWithId($this->id);
+      civicrm_api3('DataProcessorOutput', 'delete', array('id' => $this->id));
       $session->setStatus(E::ts('Data Processor Output removed'), E::ts('Removed'), 'success');
       CRM_Utils_System::redirect($redirectUrl);
     }
@@ -91,17 +114,8 @@ class CRM_Dataprocessor_Form_Output extends CRM_Core_Form {
     if ($this->id) {
       $params['id'] = $this->id;
     }
-    $result = CRM_Dataprocessor_BAO_Output::add($params);
-    $factory = dataprocessor_get_factory();
-    $outputClass  = $factory->getOutputByName($result['type']);
-    if  ($outputClass->getConfigurationUrl()) {
-      $redirectUrl = CRM_Utils_System::url($outputClass->getConfigurationUrl(), [
-        'reset' => 1,
-        'action' =>  'update',
-        'id' => $result['id'],
-        'data_processor_id' => $this->dataProcessorId
-      ]);
-    }
+    $params['configuration'] = $this->outputTypeClass->processConfiguration($values, $params);
+    $result = civicrm_api3('DataProcessorOutput', 'create', $params);
 
     CRM_Utils_System::redirect($redirectUrl);
     parent::postProcess();
diff --git a/CRM/Dataprocessor/Form/Output/API.php b/CRM/Dataprocessor/Form/Output/API.php
deleted file mode 100644
index c131840580a48d2b95a4f59c2824212e06d76c9a..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/Form/Output/API.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * Form controller class
- *
- * @see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference
- */
-class CRM_Dataprocessor_Form_Output_API extends CRM_Dataprocessor_Form_Output_AbstractOutputForm {
-
-
-  public function buildQuickForm() {
-    parent::buildQuickForm();
-    $this->add('select','permission', E::ts('Permission'), CRM_Core_Permission::basicPermissions(), true, array(
-      'style' => 'min-width:250px',
-      'class' => 'crm-select2 huge',
-      'placeholder' => E::ts('- select -'),
-    ));
-    $this->add('text', 'api_entity', E::ts('API Entity'), true);
-    $this->add('text', 'api_action', E::ts('API Action Name'), true);
-    $this->add('text', 'api_count_action', E::ts('API GetCount Action Name'), true);
-  }
-
-  function setDefaultValues() {
-    $defaults = parent::setDefaultValues();
-    if ($this->output) {
-      $defaults['permission'] = $this->output['permission'];
-      $defaults['api_entity'] = $this->output['api_entity'];
-      $defaults['api_action'] = $this->output['api_action'];
-      $defaults['api_count_action'] = $this->output['api_count_action'];
-    } else {
-      $defaults['permission'] = 'access CiviCRM';
-    }
-    return $defaults;
-  }
-
-  public function postProcess() {
-    $session = CRM_Core_Session::singleton();
-    $redirectUrl = $session->readUserContext();
-
-    $values = $this->exportValues();
-    $params['id'] = $this->id;
-    $params['permission'] = $values['permission'];
-    $params['api_entity'] = $values['api_entity'];
-    $params['api_action'] = $values['api_action'];
-    $params['api_count_action'] = $values['api_count_action'];
-    CRM_Dataprocessor_BAO_Output::add($params);
-
-    CRM_Utils_System::redirect($redirectUrl);
-    parent::postProcess();
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Output/AbstractOutputForm.php b/CRM/Dataprocessor/Form/Output/AbstractOutputForm.php
index 5ff79c19d97254d1a4c071d6de9fad4489fbb676..21d892eef6026531a76d8a4105c17499e1e365e3 100644
--- a/CRM/Dataprocessor/Form/Output/AbstractOutputForm.php
+++ b/CRM/Dataprocessor/Form/Output/AbstractOutputForm.php
@@ -31,8 +31,7 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractOutputForm extends CRM_Core
     $this->assign('id', $this->id);
 
     if ($this->id) {
-      $output = CRM_Dataprocessor_BAO_Output::getValues(array('id' => $this->id));
-      $this->output = $output[$this->id];
+      $this->output = civicrm_api3('DataProcessorOutput', 'getsingle', array('id' => $this->id));
       $this->assign('output', $output[$this->id]);
     }
 
diff --git a/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php b/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php
index 0ec54cff45bd30f75c3059ea3537883a16c11309..53e3e47366a317c60c1b8d13782b841aa0d6c691 100644
--- a/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php
+++ b/CRM/Dataprocessor/Form/Output/AbstractUIOutputForm.php
@@ -9,19 +9,19 @@ use CRM_Dataprocessor_ExtensionUtil as E;
 abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Core_Form_Search {
 
   /**
-   * @var \Civi\DataProcessor\ProcessorType\AbstractProcessorType;
+   * @var array
    */
   protected $dataProcessor;
 
   /**
-   * @var int
+   * @var \Civi\DataProcessor\ProcessorType\AbstractProcessorType;
    */
-  protected $dataProcessorId;
+  protected $dataProcessorClass;
 
   /**
-   * @var array
+   * @var int
    */
-  protected $dataProcessorBAO;
+  protected $dataProcessorId;
 
   /**
    * @var \CRM_Dataprocessor_BAO_Output
@@ -74,14 +74,12 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Co
       if (!$dao->fetch()) {
         throw new \Exception('Could not find Data Processor "' . $dataProcessorName.'"');
       }
-      $this->dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getDataProcessorById($dao->data_processor_id);
-      $this->dataProcessorId = $dao->data_processor_id;
 
-      $dataProcessorBAO = CRM_Dataprocessor_BAO_DataProcessor::getValues(array('id' => $this->dataProcessorId));
-      $this->dataProcessorBAO = $dataProcessorBAO[$this->dataProcessorId];
+      $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $dao->data_processor_id));
+      $this->dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor);
+      $this->dataProcessorId = $dao->data_processor_id;
 
-      $output = CRM_Dataprocessor_BAO_Output::getValues(['id' => $dao->output_id]);
-      $this->dataProcessorOutput = $output[$dao->output_id];
+      $this->dataProcessorOutput = civicrm_api3('DataProcessorOutput', 'getsingle', array('id' => $dao->output_id));
       $this->assign('output', $this->dataProcessorOutput);
 
       if (!$this->isConfigurationValid()) {
@@ -96,8 +94,8 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Co
    * @return bool
    */
   protected function hasRequiredFilters() {
-    if ($this->dataProcessor->getFilterHandlers()) {
-      foreach ($this->dataProcessor->getFilterHandlers() as $filter) {
+    if ($this->dataProcessorClass->getFilterHandlers()) {
+      foreach ($this->dataProcessorClass->getFilterHandlers() as $filter) {
         if ($filter->isRequired()) {
           return true;
         }
@@ -113,28 +111,9 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Co
    */
   protected function validateFilters() {
     $errors = array();
-    if ($this->dataProcessor->getFilterHandlers()) {
-      foreach ($this->dataProcessor->getFilterHandlers() as $filter) {
-        if ($filter->isRequired()) {
-          $isFilterSet = FALSE;
-          $filterSpec = $filter->getFieldSpecification();
-          $filterName = $filterSpec->alias;
-          if ($filterSpec->type == 'Date') {
-            $relative = CRM_Utils_Array::value("{$filterName}_relative", $this->_formValues);
-            $from = CRM_Utils_Array::value("{$filterName}_from", $this->_formValues);
-            $to = CRM_Utils_Array::value("{$filterName}_to", $this->_formValues);
-            $fromTime = CRM_Utils_Array::value("{$filterName}_from_time", $this->_formValues);
-            $toTime = CRM_Utils_Array::value("{$filterName}_to_time", $this->_formValues);
-
-            list($from, $to) = CRM_Utils_Date::getFromTo($relative, $from, $to, $fromTime, $toTime);
-            if (!$from && !$to) {
-              $errors[$filterName . '_relative'] = E::ts('Field %1 is required', [1 => $filterSpec->title]);
-            }
-          }
-          elseif (!isset($this->_formValues[$filterName . '_op']) || !(isset($this->_formValues[$filterName . '_value']) && $this->_formValues[$filterName . '_value'])) {
-            $errors[$filterName . '_value'] = E::ts('Field %1 is required', [1 => $filterSpec->title]);
-          }
-        }
+    if ($this->dataProcessorClass->getFilterHandlers()) {
+      foreach ($this->dataProcessorClass->getFilterHandlers() as $filter) {
+        $errors = array_merge($errors, $filter->validateSubmittedFilterParams($this->_formValues));
       }
     }
     return $errors;
@@ -148,243 +127,27 @@ abstract class CRM_Dataprocessor_Form_Output_AbstractUIOutputForm extends CRM_Co
   public static function applyFilters(\Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor, $submittedValues) {
     if ($dataProcessor->getFilterHandlers()) {
       foreach ($dataProcessor->getFilterHandlers() as $filter) {
-        $isFilterSet = FALSE;
-        $filterSpec = $filter->getFieldSpecification();
-        $filterName = $filterSpec->alias;
-
-        foreach($submittedValues as $k => $v) {
-          if (strpos($k, $filterName) === 0) {
-            $filterParamSet[$k] = $v;
-          }
-        }
-
-        if ($filterSpec->type == 'Date') {
-          $isFilterSet = self::applyDateFilter($filter, $submittedValues);
-        }
-        elseif (isset($submittedValues[$filterName . '_op'])) {
-          switch ($submittedValues[$filterName . '_op']) {
-            case 'IN':
-              if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
-                $filterParams = [
-                  'op' => 'IN',
-                  'value' => $submittedValues[$filterName . '_value'],
-                ];
-                $filter->setFilter($filterParams);
-                $isFilterSet = TRUE;
-              }
-              break;
-            case 'NOT IN':
-              if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
-                $filterParams = [
-                  'op' => 'NOT IN',
-                  'value' => $submittedValues[$filterName . '_value'],
-                ];
-                $filter->setFilter($filterParams);
-                $isFilterSet = TRUE;
-              }
-              break;
-            case '=':
-            case '!=':
-            case '>':
-            case '<':
-            case '>=':
-            case '<=':
-              if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
-                $filterParams = [
-                  'op' => $submittedValues[$filterName . '_op'],
-                  'value' => $submittedValues[$filterName . '_value'],
-                ];
-                $filter->setFilter($filterParams);
-                $isFilterSet = TRUE;
-              }
-              break;
-            case 'has':
-              if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
-                $filterParams = [
-                  'op' => 'LIKE',
-                  'value' => '%' . $submittedValues[$filterName . '_value'] . '%',
-                ];
-                $filter->setFilter($filterParams);
-                $isFilterSet = TRUE;
-              }
-              break;
-            case 'nhas':
-              if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
-                $filterParams = [
-                  'op' => 'NOT LIKE',
-                  'value' => '%' . $submittedValues[$filterName . '_value'] . '%',
-                ];
-                $filter->setFilter($filterParams);
-                $isFilterSet = TRUE;
-              }
-              break;
-            case 'sw':
-              if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
-                $filterParams = [
-                  'op' => 'LIKE',
-                  'value' => $submittedValues[$filterName . '_value'] . '%',
-                ];
-                $filter->setFilter($filterParams);
-                $isFilterSet = TRUE;
-              }
-              break;
-            case 'ew':
-              if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
-                $filterParams = [
-                  'op' => 'LIKE',
-                  'value' => '%' . $submittedValues[$filterName . '_value'],
-                ];
-                $filter->setFilter($filterParams);
-                $isFilterSet = TRUE;
-              }
-              break;
-          }
-        }
-        if ($filter->isRequired() && !$isFilterSet) {
-          throw new \Exception('Field ' . $filterSpec->title . ' is required');
-        }
+       $filter->applyFilterFromSubmittedFilterParams($submittedValues);
       }
     }
   }
 
-  /**
-   * @param \Civi\DataProcessor\FilterHandler\AbstractFilterHandler $filter
-   * @param array $submittedValues
-   * @return string|null
-   */
-  protected static function applyDateFilter(\Civi\DataProcessor\FilterHandler\AbstractFilterHandler $filter, $submittedValues) {
-    $filterName = $filter->getFieldSpecification()->alias;
-    $type = $filter->getFieldSpecification()->type;
-    $relative = CRM_Utils_Array::value("{$filterName}_relative", $submittedValues);
-    $from = CRM_Utils_Array::value("{$filterName}_from", $submittedValues);
-    $to = CRM_Utils_Array::value("{$filterName}_to", $submittedValues);
-    $fromTime = CRM_Utils_Array::value("{$filterName}_from_time", $submittedValues);
-    $toTime = CRM_Utils_Array::value("{$filterName}_to_time", $submittedValues);
-
-    list($from, $to) = CRM_Utils_Date::getFromTo($relative, $from, $to, $fromTime, $toTime);
-    if ($from && $to) {
-      $from = ($type == "Date") ? substr($from, 0, 8) : $from;
-      $to = ($type == "Date") ? substr($to, 0, 8) : $to;
-      $filter->setFilter(array(
-        'op' => 'BETWEEN',
-        'value' => array($from, $to),
-      ));
-      return TRUE;
-    } elseif ($from) {
-      $from = ($type == "Date") ? substr($from, 0, 8) : $from;
-      $filter->setFilter(array(
-        'op' => '>=',
-        'value' => $from,
-      ));
-      return TRUE;
-    } elseif ($to) {
-      $to = ($type == "Date") ? substr($to, 0, 8) : $to;
-      $filter->setFilter(array(
-        'op' => '<=',
-        'value' => $to,
-      ));
-      return TRUE;
-    }
-    return FALSE;
-  }
-
   /**
    * Build the criteria form
    */
   protected function buildCriteriaForm() {
-    $count = 1;
     $filterElements = array();
-    $types = \CRM_Utils_Type::getValidTypes();
-    if ($this->dataProcessor->getFilterHandlers()) {
-      foreach ($this->dataProcessor->getFilterHandlers() as $filterHandler) {
+    if ($this->dataProcessorClass->getFilterHandlers()) {
+      foreach ($this->dataProcessorClass->getFilterHandlers() as $filterHandler) {
         $fieldSpec = $filterHandler->getFieldSpecification();
-        $type = \CRM_Utils_Type::T_STRING;
-        if (isset($types[$fieldSpec->type])) {
-          $type = $types[$fieldSpec->type];
-        }
         if (!$fieldSpec) {
           continue;
         }
-        $filter['title'] = $fieldSpec->title;
-        if ($filterHandler->isRequired()) {
-          $filter['title'] .= ' <span class="crm-marker">*</span>';
-        }
-        $filter['type'] = $fieldSpec->type;
-        $operations = $this->getOperatorOptions($fieldSpec);
-        if ($fieldSpec->getOptions()) {
-          $element = $this->addElement('select', "{$fieldSpec->alias}_op", E::ts('Operator:'), $operations);
-          $this->addElement('select', "{$fieldSpec->alias}_value", NULL, $fieldSpec->getOptions(), [
-            'style' => 'min-width:250px',
-            'class' => 'crm-select2 huge',
-            'multiple' => TRUE,
-            'placeholder' => E::ts('- select -'),
-          ]);
-        }
-        else {
-          switch ($type) {
-            case \CRM_Utils_Type::T_DATE:
-              CRM_Core_Form_Date::buildDateRange($this, $fieldSpec->alias, $count, '_from', '_to', E::ts('From:'), $filterHandler->isRequired(), $operations);
-              $count++;
-              break;
-            case CRM_Report_Form::OP_INT:
-            case CRM_Report_Form::OP_FLOAT:
-              // and a min value input box
-              $this->add('text', "{$fieldSpec->alias}_min", E::ts('Min'));
-              // and a max value input box
-              $this->add('text', "{$fieldSpec->alias}_max", E::ts('Max'));
-            default:
-              // default type is string
-              $this->addElement('select', "{$fieldSpec->alias}_op", E::ts('Operator:'), $operations,
-                ['onchange' => "return showHideMaxMinVal( '$fieldSpec->alias', this.value );"]
-              );
-              // we need text box for value input
-              $this->add('text', "{$fieldSpec->alias}_value", NULL, ['class' => 'huge']);
-              break;
-          }
-        }
-        $filterElements[$fieldSpec->alias] = $filter;
+        $filterElements[$fieldSpec->alias]['filter'] = $filterHandler->addToFilterForm($this);
+        $filterElements[$fieldSpec->alias]['template'] = $filterHandler->getTemplateFileName();
       }
       $this->assign('filters', $filterElements);
     }
   }
 
-  protected function getOperatorOptions(\Civi\DataProcessor\DataSpecification\FieldSpecification $fieldSpec) {
-    if ($fieldSpec->getOptions()) {
-      return array(
-        'IN' => E::ts('Is one of'),
-        'NOT IN' => E::ts('Is not one of'),
-      );
-    }
-    $types = \CRM_Utils_Type::getValidTypes();
-    $type = \CRM_Utils_Type::T_STRING;
-    if (isset($types[$fieldSpec->type])) {
-      $type = $types[$fieldSpec->type];
-    }
-    switch ($type) {
-      case \CRM_Utils_Type::T_DATE:
-        return array();
-        break;
-      case \CRM_Utils_Type::T_INT:
-      case \CRM_Utils_Type::T_FLOAT:
-        return array(
-          '=' => E::ts('Is equal to'),
-          '<=' => E::ts('Is less than or equal to'),
-          '>=' => E::ts('Is greater than or equal to'),
-          '<' => E::ts('Is less than'),
-          '>' => E::ts('Is greater than'),
-          '!=' => E::ts('Is not equal to'),
-        );
-        break;
-    }
-    return array(
-      '=' => E::ts('Is equal to'),
-      '!=' => E::ts('Is not equal to'),
-      'has' => E::ts('Contains'),
-      'sw' => E::ts('Starts with'),
-      'ew' => E::ts('Ends with'),
-      'nhas' => E::ts('Does not contain'),
-    );
-  }
-
-
 }
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Source.php b/CRM/Dataprocessor/Form/Source.php
index bee91b5b1b1e3406b8f7bddd4dd4bffd5f740ed3..25ed80a51a4d919663f77597fa74f75788301bd4 100644
--- a/CRM/Dataprocessor/Form/Source.php
+++ b/CRM/Dataprocessor/Form/Source.php
@@ -11,29 +11,68 @@ class CRM_Dataprocessor_Form_Source extends CRM_Core_Form {
 
   private $dataProcessorId;
 
+  private $dataProcessor;
+
+  /**
+   * @var Civi\DataProcessor\ProcessorType\AbstractProcessorType
+   */
+  private $dataProcessorClass;
+
   private $id;
 
   private $isFirstDataSource = true;
 
+  private $source;
+
+  /**
+   * @var Civi\DataProcessor\Source\SourceInterface
+   */
+  private $sourceClass;
+
+  /**
+   * @var Civi\DataProcessor\DataFlow\MultipleDataFlows\JoinInterface
+   */
+  private $joinClass;
+
+  private $snippet;
+
   /**
    * Function to perform processing before displaying form (overrides parent function)
    *
    * @access public
    */
   function preProcess() {
-    $session = CRM_Core_Session::singleton();
+    $this->snippet = CRM_Utils_Request::retrieve('snippet', 'String');
+    if ($this->snippet) {
+      $this->assign('suppressForm', TRUE);
+      $this->controller->_generateQFKey = FALSE;
+      $block = CRM_Utils_Request::retrieve('block', 'String', $this, FALSE, 'configuration');
+      $this->assign('block', $block);
+    }
+
+    $factory = dataprocessor_get_factory();
+
     $this->dataProcessorId = CRM_Utils_Request::retrieve('data_processor_id', 'Integer');
     $this->assign('data_processor_id', $this->dataProcessorId);
+    if ($this->dataProcessorId) {
+      $this->dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $this->dataProcessorId));
+      $this->dataProcessorClass = CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($this->dataProcessor);
+    }
 
     $this->id = CRM_Utils_Request::retrieve('id', 'Integer');
     $this->assign('id', $this->id);
 
-    $sources = CRM_Dataprocessor_BAO_Source::getValues(array('data_processor_id' => $this->dataProcessorId));
+    $this->assign('has_configuration', false);
+
+    $sources = civicrm_api3('DataProcessorSource', 'get', array('data_processor_id' => $this->dataProcessorId, 'options' => array('limit' => 0)));
     if ($this->id) {
-      $source = CRM_Dataprocessor_BAO_Source::getValues(array('id' => $this->id));
-      $this->assign('source', $source[$this->id]);
+      $this->source = civicrm_api3('DataProcessorSource', 'getsingle', array('id' => $this->id));
+      $this->assign('source', $this->source);
+      $this->sourceClass = CRM_Dataprocessor_BAO_DataProcessorSource::sourceToSourceClass($this->source);
+      $this->assign('has_configuration', $this->sourceClass->hasConfiguration());
+
       $i = 0;
-      foreach($sources as $s) {
+      foreach($sources['values'] as $s) {
         if ($s['id'] == $this->id) {
           $this->isFirstDataSource = $i > 0 ? false : true;
           break;
@@ -41,21 +80,48 @@ class CRM_Dataprocessor_Form_Source extends CRM_Core_Form {
         $i++;
       }
     } else {
-      $this->isFirstDataSource = count($sources) > 0 ? false : true;
+      $this->isFirstDataSource = count($sources['values']) > 0 ? false : true;
+      $this->source['data_processor_id'] = $this->dataProcessorId;
     }
     $this->assign('is_first_data_source', $this->isFirstDataSource);
 
+    $type = CRM_Utils_Request::retrieve('type', 'String');
+    if ($type) {
+      $this->source['type'] = $type;
+      $this->sourceClass = CRM_Dataprocessor_BAO_DataProcessorSource::sourceToSourceClass($this->source);
+      $this->assign('has_configuration', $this->sourceClass->hasConfiguration());
+      if ($this->sourceClass && !$this->id) {
+        $this->source['configuration'] = $this->sourceClass->getDefaultConfiguration();
+      }
+    }
+
+    $join_type = CRM_Utils_Request::retrieve('join_type', 'String');
+    if ($join_type) {
+      $this->source['join_type'] = $join_type;
+    }
+
+    $this->assign('has_join_configuration', false);
+    if (!$this->isFirstDataSource && isset($this->source['join_type']) && $this->source['join_type']) {
+      $this->joinClass = $factory->getJoinByName($this->source['join_type']);
+      $this->assign('has_join_configuration', $this->joinClass->hasConfiguration());
+    }
+
+    if (!isset($this->source['join_configuration']) || !is_array($this->source['join_configuration'])) {
+      $this->source['join_configuration'] = array();
+    }
+
     $title = E::ts('Data Processor Source');
     CRM_Utils_System::setTitle($title);
-
-    $url = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('id' => $this->dataProcessorId, 'action' => 'update', 'reset' => 1));
-    $session->pushUserContext($url);
   }
 
   public function buildQuickForm() {
     $this->add('hidden', 'data_processor_id');
     $this->add('hidden', 'id');
-    if ($this->_action != CRM_Core_Action::DELETE) {
+    if ($this->_action == CRM_Core_Action::DELETE) {
+      $this->addButtons(array(
+        array('type' => 'next', 'name' => E::ts('Delete'), 'isDefault' => TRUE,),
+        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
+    } else {
       $this->add('text', 'name', E::ts('Name'), array('size' => CRM_Utils_Type::HUGE), FALSE);
       $this->add('text', 'title', E::ts('Title'), array('size' => CRM_Utils_Type::HUGE), TRUE);
 
@@ -69,18 +135,29 @@ class CRM_Dataprocessor_Form_Source extends CRM_Core_Form {
 
       if (!$this->isFirstDataSource) {
         $joins = [' - select - '] + $factory->getJoins();
-        $this->add('select', 'join_type', ts('Select Join Type'), $joins, TRUE, ['class' => 'crm-select2']);
+        $this->add('select', 'join_type', ts('Select Join Type'), $joins, TRUE, array(
+          'style' => 'min-width:250px',
+          'class' => 'crm-select2 huge',
+          'placeholder' => E::ts('- select -'),
+        ));
+        if ($this->joinClass && $this->joinClass->hasConfiguration()) {
+          $joinableToSources = array();
+          foreach($this->dataProcessorClass->getDataSources() as $source) {
+            if ($this->sourceClass && $this->sourceClass->getSourceName() == $source->getSourceName()) {
+              break;
+            }
+            $joinableToSources[] = $source;
+          }
+          $this->joinClass->buildConfigurationForm($this, $this->sourceClass, $joinableToSources, $this->source['join_configuration']);
+          $this->assign('join_configuration_template', $this->joinClass->getConfigurationTemplateFileName());
+        }
       }
-    }
-    if ($this->_action == CRM_Core_Action::ADD) {
-      $this->addButtons(array(
-        array('type' => 'next', 'name' => E::ts('Next'), 'isDefault' => TRUE,),
-        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
-    } elseif ($this->_action == CRM_Core_Action::DELETE) {
-      $this->addButtons(array(
-        array('type' => 'next', 'name' => E::ts('Delete'), 'isDefault' => TRUE,),
-        array('type' => 'cancel', 'name' => E::ts('Cancel'))));
-    } else {
+
+      if ($this->sourceClass && $this->sourceClass->hasConfiguration()) {
+        $this->sourceClass->buildConfigurationForm($this, $this->source);
+        $this->assign('configuration_template', $this->sourceClass->getConfigurationTemplateFileName());
+      }
+
       $this->addButtons(array(
         array('type' => 'next', 'name' => E::ts('Save'), 'isDefault' => TRUE,),
         array('type' => 'cancel', 'name' => E::ts('Cancel'))));
@@ -93,97 +170,61 @@ class CRM_Dataprocessor_Form_Source extends CRM_Core_Form {
     $defaults['data_processor_id'] = $this->dataProcessorId;
     $defaults['id'] = $this->id;
 
-    $source = CRM_Dataprocessor_BAO_Source::getValues(array('id' => $this->id));
-    if (isset($source[$this->id]['type'])) {
-      $defaults['type'] = $source[$this->id]['type'];
+    if (isset($this->source['type'])) {
+      $defaults['type'] = $this->source['type'];
     }
-    if (isset($source[$this->id]['title'])) {
-      $defaults['title'] = $source[$this->id]['title'];
+    if (isset($this->source['title'])) {
+      $defaults['title'] = $this->source['title'];
     }
-    if (isset($source[$this->id]['name'])) {
-      $defaults['name'] = $source[$this->id]['name'];
+    if (isset($this->source['name'])) {
+      $defaults['name'] = $this->source['name'];
     }
-    if (isset($source[$this->id]['join_type'])) {
-      $defaults['join_type'] = $source[$this->id]['join_type'];
+    if (isset($this->source['join_type'])) {
+      $defaults['join_type'] = $this->source['join_type'];
     }
     return $defaults;
   }
 
   public function postProcess() {
     $session = CRM_Core_Session::singleton();
-    $backUrl = $redirectUrl = $session->readUserContext();
+    $redirectUrl = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('reset' => 1, 'action' => 'update', 'id' => $this->dataProcessorId));
     if ($this->_action == CRM_Core_Action::DELETE) {
-      CRM_Dataprocessor_BAO_Source::deleteWithId($this->id);
+      civicrm_api3('DataProcessorSource', 'delete', array('id' => $this->id));
       $session->setStatus(E::ts('Data Processor Source removed'), E::ts('Removed'), 'success');
       CRM_Utils_System::redirect($redirectUrl);
     }
 
-    $source = CRM_Dataprocessor_BAO_Source::getValues(array('id' => $this->id));
-
     $values = $this->exportValues();
 
     $factory = dataprocessor_get_factory();
-    $sourceClass = $factory->getDataSourceByName($values['type']);
 
     if (!empty($values['name'])) {
       $params['name'] = $values['name'];
-    } else {
-      $params['name'] = CRM_Dataprocessor_BAO_Source::buildNameFromTitle($values['title']);
     }
     $params['title'] = $values['title'];
     $params['type'] = $values['type'];
-    if (!$this->isFirstDataSource) {
-      $params['join_type'] = $values['join_type'];
-    } else {
-      $params['join_type'] = '';
-    }
     if ($this->dataProcessorId) {
       $params['data_processor_id'] = $this->dataProcessorId;
     }
     if ($this->id) {
       $params['id'] = $this->id;
-    } else {
-      $params['configuration'] = $sourceClass->getDefaultConfiguration();
-    }
-    if (isset($source[$this->id])) {
-      $params['join_configuration'] = $source[$this->id]['join_configuration'];
     }
+    $this->sourceClass = CRM_Dataprocessor_BAO_DataProcessorSource::sourceToSourceClass($params);
 
-
-    $result = CRM_Dataprocessor_BAO_Source::add($params);
-
-
-    $configurationUrl = false;
-    if ($sourceClass->getConfigurationUrl()) {
-      $configurationUrl = CRM_Utils_System::url($sourceClass->getConfigurationUrl(), [
-        'reset' => 1,
-        'action' => 'add',
-        'source_id' => $result['id'],
-        'data_processor_id' => $this->dataProcessorId
-      ]);
-      $redirectUrl = $configurationUrl;
+    if ($this->sourceClass && $this->sourceClass->hasConfiguration()) {
+      $params['configuration'] = $this->sourceClass->processConfiguration($values);
     }
 
-    if (!$this->isFirstDataSource && $this->_action == CRM_Core_Action::ADD) {
-      $joinClass = $factory->getJoinByName($values['join_type']);
-      if ($joinClass->getConfigurationUrl()) {
-        $joinUrl = CRM_Utils_System::url($joinClass->getConfigurationUrl(), [
-          'reset' => 1,
-          'action' => 'add',
-          'source_id' => $result['id'],
-          'data_processor_id' => $this->dataProcessorId
-        ]);
-        $session->pushUserContext($backUrl);
-        if ($configurationUrl) {
-          $session->pushUserContext($configurationUrl);
-        }
-        $redirectUrl = $joinUrl;
-      } else {
-        $session->pushUserContext($backUrl);
+    if (!$this->isFirstDataSource) {
+      $params['join_type'] = $values['join_type'];
+      if ($this->joinClass && $this->joinClass->hasConfiguration()) {
+        $params['join_configuration'] = $this->joinClass->processConfiguration($values, $this->sourceClass);
       }
-    } elseif ($this->_action == CRM_Core_Action::ADD) {
-      $session->pushUserContext($backUrl);
+    } else {
+      $params['join_type'] = '';
     }
+    $result = civicrm_api3('DataProcessorSource', 'create', $params);
+
     CRM_Utils_System::redirect($redirectUrl);
     parent::postProcess();
   }
@@ -218,13 +259,14 @@ class CRM_Dataprocessor_Form_Source extends CRM_Core_Form {
       $id = $fields['id'];
     }
     if (empty($fields['name'])) {
-      $fields['name'] = CRM_Dataprocessor_BAO_Source::buildNameFromTitle($fields['title']);
+      $fields['name'] = CRM_Dataprocessor_BAO_DataProcessorSource::checkName($fields['title'], $fields['data_processor_id'], $id);
     }
-    if (!CRM_Dataprocessor_BAO_Source::isNameValid($fields['name'], $fields['data_processor_id'], $id)) {
+    if (!CRM_Dataprocessor_BAO_DataProcessorSource::isNameValid($fields['name'], $fields['data_processor_id'], $id)) {
       $errors['name'] = E::ts('There is already a data source with this name');
       return $errors;
     }
     return TRUE;
   }
 
+
 }
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Source/BaseForm.php b/CRM/Dataprocessor/Form/Source/BaseForm.php
deleted file mode 100644
index ebe1104c22b2230c510de5d5ba46536f0ded0e08..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/Form/Source/BaseForm.php
+++ /dev/null
@@ -1,80 +0,0 @@
-<?php
-/**
- * @author Jaap Jansma <jaap.jansma@civicoop.org>
- * @license AGPL-3.0
- */
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-class CRM_Dataprocessor_Form_Source_BaseForm extends CRM_Core_Form {
-
-  protected $dataProcessorId;
-
-  protected $source_id;
-
-  /**
-   * @var \Civi\DataProcessor\Source\SourceInterface
-   */
-  protected $sourceClass;
-
-  /**
-   * @var array
-   *   The source object
-   */
-  protected $source;
-
-  /**
-   * Function to perform processing before displaying form (overrides parent function)
-   *
-   * @access public
-   */
-  function preProcess() {
-    $session = CRM_Core_Session::singleton();
-    $this->dataProcessorId = CRM_Utils_Request::retrieve('data_processor_id', 'Integer');
-    $this->assign('data_processor_id', $this->dataProcessorId);
-
-    $this->source_id = CRM_Utils_Request::retrieve('source_id', 'Integer', CRM_Core_DAO::$_nullObject, TRUE);
-    $this->assign('source_id', $this->source_id);
-
-    $source = CRM_Dataprocessor_BAO_Source::getValues(array('id' => $this->source_id));
-    $this->source = $source[$this->source_id];
-    $this->assign('source', $this->source);
-
-    $factory = dataprocessor_get_factory();
-    $this->sourceClass = $factory->getDataSourceByName($this->source['type']);
-    $this->sourceClass->setSourceName($this->source['name']);
-    $this->sourceClass->setSourceTitle($this->source['title']);
-
-    $title = E::ts('Data Processor Source Configuration');
-    CRM_Utils_System::setTitle($title);
-
-    $url = CRM_Utils_System::url('civicrm/dataprocessor/form/edit', array('id' => $this->dataProcessorId, 'action' => 'update', 'reset' => 1));
-    $session->pushUserContext($url);
-  }
-
-  public function buildQuickForm() {
-    $this->add('hidden', 'data_processor_id');
-    $this->add('hidden', 'source_id');
-
-    $this->addButtons(array(
-      array('type' => 'next', 'name' => E::ts('Save'), 'isDefault' => TRUE,),
-      array('type' => 'cancel', 'name' => E::ts('Cancel'))
-    ));
-    parent::buildQuickForm();
-  }
-
-  function setDefaultValues() {
-    $defaults = [];
-    $defaults['data_processor_id'] = $this->dataProcessorId;
-    $defaults['source_id'] = $this->source_id;
-
-    return $defaults;
-  }
-
-  public function postProcess() {
-    $session = CRM_Core_Session::singleton();
-    CRM_Utils_System::redirect($session->readUserContext());
-    parent::postProcess();
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Source/Configuration.php b/CRM/Dataprocessor/Form/Source/Configuration.php
deleted file mode 100644
index e4e35b12daaf90e27e27b6d0c833351565aba22c..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/Form/Source/Configuration.php
+++ /dev/null
@@ -1,112 +0,0 @@
-<?php
-/**
- * @author Jaap Jansma <jaap.jansma@civicoop.org>
- * @license AGPL-3.0
- */
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-class CRM_Dataprocessor_Form_Source_Configuration extends CRM_Dataprocessor_Form_Source_BaseForm {
-
-  public function buildQuickForm() {
-    parent::buildQuickForm();
-
-    $this->addFieldsForFiltering();
-  }
-
-  function setDefaultValues() {
-    $defaults = parent::setDefaultValues();
-    if (isset($this->source['configuration']['filter'])) {
-      foreach($this->source['configuration']['filter'] as $alias => $filter) {
-        $defaults[$alias.'_op'] = $filter['op'];
-        $defaults[$alias.'_value'] = $filter['value'];
-      }
-    }
-
-    return $defaults;
-  }
-
-  public function postProcess() {
-    if ($this->dataProcessorId) {
-      $params['data_processor_id'] = $this->dataProcessorId;
-    }
-    if ($this->source_id) {
-      $params['id'] = $this->source_id;
-    }
-
-    $params['configuration']['filter'] = $this->postProcessFieldsForFiltering();
-    CRM_Dataprocessor_BAO_Source::add($params);
-    parent::postProcess();
-  }
-
-
-  /**
-   * Add a data specification to the form for filtering.
-   */
-  protected function addFieldsForFiltering() {
-    $fields = array();
-    foreach($this->sourceClass->getAvailableFilterFields()->getFields() as $fieldSpec) {
-      $alias = $fieldSpec->name;
-      switch ($fieldSpec->type) {
-        case 'Boolean':
-          $fields[$alias] = $fieldSpec->title;
-          $this->addElement('select', "{$alias}_op", ts('Operator:'), [
-            '=' => E::ts('Is equal to'),
-            '!=' => E::ts('Is not equal to'),
-          ]);
-          if (!empty($fieldSpec->getOptions())) {
-            $this->addElement('select', "{$alias}_value", $fieldSpec->title, array('' => E::ts(' - Select - ')) + $fieldSpec->getOptions());
-          }
-          break;
-        default:
-          if ($fieldSpec->getOptions()) {
-            $fields[$alias] = $fieldSpec->title;
-            $this->addElement('select', "{$alias}_op", ts('Operator:'), [
-              'IN' => E::ts('Is one of'),
-              'NOT IN' => E::ts('Is not one of'),
-            ]);
-            $this->addElement('select', "{$alias}_value", $fieldSpec->title, $fieldSpec->getOptions(), array(
-              'style' => 'min-width:250px',
-              'class' => 'crm-select2 huge',
-              'multiple' => 'multiple',
-              'placeholder' => E::ts('- select -'),
-            ));
-          }
-      }
-    }
-    $this->assign('filter_fields', $fields);
-  }
-  /**
-   * Create a configuration filtering array
-   *
-   * @return array
-   */
-  protected function postProcessFieldsForFiltering() {
-    $values = $this->exportValues();
-    $filter_config = array();
-    foreach($this->sourceClass->getAvailableFilterFields()->getFields() as $fieldSpec) {
-      $alias = $fieldSpec->name;
-      if ($this->valueSubmitted($alias.'_value', $values)) {
-        $filter_config[$alias] = array(
-          'op' => $values[$alias.'_op'],
-          'value' => $values[$alias.'_value']
-        );
-      }
-    }
-    return $filter_config;
-  }
-
-  protected function valueSubmitted($field, $values) {
-    if (!isset($values[$field])) {
-      return false;
-    }
-    if (is_array($values[$field]) && count($values[$field]) === 0) {
-      return false;
-    }
-    if (is_string($values[$field]) && strlen($values[$field]) === 0) {
-      return false;
-    }
-    return true;
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Source/Csv.php b/CRM/Dataprocessor/Form/Source/Csv.php
deleted file mode 100644
index 1b0ca38f301c27043474c4255b33815092857294..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/Form/Source/Csv.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-/**
- * @author Jaap Jansma <jaap.jansma@civicoop.org>
- * @license AGPL-3.0
- */
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * Form controller class
- *
- * @see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference
- */
-class CRM_Dataprocessor_Form_Source_Csv extends CRM_Dataprocessor_Form_Source_BaseForm {
-
-  public function buildQuickForm() {
-    parent::buildQuickForm();
-    $this->add('text', 'uri', E::ts('URI'), true);
-    $this->add('text', 'delimiter', E::ts('Field delimiter'), true);
-    $this->add('text', 'enclosure', E::ts('Field enclosure character'), true);
-    $this->add('text', 'escape', E::ts('Escape character'), true);
-    $this->add('checkbox', 'first_row_as_header', E::ts('First row contains column names'));
-  }
-
-  function setDefaultValues() {
-    $defaults = parent::setDefaultValues();
-    foreach($this->source['configuration'] as $field => $value) {
-      $defaults[$field] = $value;
-    }
-    if (!isset($defaults['delimiter'])) {
-      $defaults['delimiter'] = ',';
-    }
-    if (!isset($defaults['enclosure'])) {
-      $defaults['enclosure'] = '"';
-    }
-    if (!isset($defaults['escape'])) {
-      $defaults['escape'] = '\\';
-    }
-    return $defaults;
-  }
-
-  public function postProcess() {
-    $values = $this->exportValues();
-    if ($this->dataProcessorId) {
-      $params['data_processor_id'] = $this->dataProcessorId;
-    }
-    if ($this->source_id) {
-      $params['id'] = $this->source_id;
-    }
-
-    $params['configuration']['uri'] = $values['uri'];
-    $params['configuration']['delimiter'] = $values['delimiter'];
-    $params['configuration']['enclosure'] = $values['enclosure'];
-    $params['configuration']['escape'] = $values['escape'];
-    $params['configuration']['first_row_as_header'] = $values['first_row_as_header'];
-    CRM_Dataprocessor_BAO_Source::add($params);
-    parent::postProcess();
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Form/Source/Relationship.php b/CRM/Dataprocessor/Form/Source/Relationship.php
deleted file mode 100644
index 35e09e457a53c1aa1fa817e823494ed2bc983109..0000000000000000000000000000000000000000
--- a/CRM/Dataprocessor/Form/Source/Relationship.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * Form controller class
- *
- * @see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference
- */
-class CRM_Dataprocessor_Form_Source_Relationship extends CRM_Dataprocessor_Form_Source_BaseForm {
-
-}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Status.php b/CRM/Dataprocessor/Status.php
new file mode 100644
index 0000000000000000000000000000000000000000..ebe8295d332f15febc1f9db3dbb8eb17f048b020
--- /dev/null
+++ b/CRM/Dataprocessor/Status.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * @author Jaap Jansma <jaap.jansma@civicoop.org>
+ * @license AGPL-3.0
+ */
+
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+class CRM_Dataprocessor_Status {
+
+  const STATUS_IN_DATABASE = 1;
+  const STATUS_IN_CODE = 2;
+  const STATUS_OVERRIDDEN = 3;
+
+  /**
+   * Returns a textual representation of the status
+   *
+   * @param $status
+   * @return string
+   */
+  public static function statusToLabel($status) {
+    switch ($status) {
+      case CRM_Dataprocessor_Status::STATUS_IN_CODE:
+        return E::ts('In code');
+        break;
+      case CRM_Dataprocessor_Status::STATUS_OVERRIDDEN:
+        return E::ts('Overridden');
+        break;
+      case CRM_Dataprocessor_Status::STATUS_IN_DATABASE:
+        return E::ts('In database');
+        break;
+    }
+    return E::ts('Unknown');
+  }
+
+}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Utils/DataSourceFields.php b/CRM/Dataprocessor/Utils/DataSourceFields.php
new file mode 100644
index 0000000000000000000000000000000000000000..acd5a9e19809358956a4c7d113f4fe7bc52731b7
--- /dev/null
+++ b/CRM/Dataprocessor/Utils/DataSourceFields.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * @author Jaap Jansma <jaap.jansma@civicoop.org>
+ * @license AGPL-3.0
+ */
+
+use Civi\DataProcessor\Source\SourceInterface;
+
+class CRM_Dataprocessor_Utils_DataSourceFields {
+
+  /**
+   * Returns an array with the name of the field as the key and the label of the field as the value.
+   *
+   * @oaram int $dataProcessorId
+   * @return array
+   * @throws \Exception
+   */
+  public static function getAvailableFieldsInDataSources($dataProcessorId) {
+    $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $dataProcessorId));
+    $dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($dataProcessor);
+    $fieldSelect = array();
+    foreach($dataProcessorClass->getDataSources() as $dataSource) {
+      $fieldSelect = array_merge($fieldSelect, self::getAvailableFieldsInDataSource($dataSource, $dataSource->getSourceTitle().' :: ', $dataSource->getSourceName().'::'));
+    }
+    return $fieldSelect;
+  }
+
+  /**
+   * Returns an array with the name of the field as the key and the label of the field as the value.
+   *
+   * @oaram SourceInterface $dataSource
+   * @return array
+   * @throws \Exception
+   */
+  public static function getAvailableFieldsInDataSource(SourceInterface $dataSource, $titlePrefix='', $namePrefix='') {
+    $fieldSelect = array();
+    foreach($dataSource->getAvailableFilterFields()->getFields() as $field) {
+      $fieldSelect[$namePrefix.$field->name] = $titlePrefix.$field->title;
+    }
+    return $fieldSelect;
+  }
+
+}
\ No newline at end of file
diff --git a/CRM/Dataprocessor/Utils/Importer.php b/CRM/Dataprocessor/Utils/Importer.php
index fcd441cf19c85b87c35a215559d0bf0b006cf221..1d88647f45a897f1e145e05beb6d61db3ae12d57 100644
--- a/CRM/Dataprocessor/Utils/Importer.php
+++ b/CRM/Dataprocessor/Utils/Importer.php
@@ -6,28 +6,103 @@
 
 class CRM_Dataprocessor_Utils_Importer {
 
-  public static function import($data, $filename) {
-    $data_processor_id = CRM_Dataprocessor_BAO_DataProcessor::getId($data['name']);
-    $status = CRM_Dataprocessor_BAO_DataProcessor::getStatus($data['name']);
+  /**
+   * Exports a data processor
+   *
+   * Returns the array with the whole configuration.
+   *
+   * @param $data_processor_id
+   * @return array
+   * @throws \Exception
+   */
+  public static function export($data_processor_id) {
+    $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $data_processor_id));
+    unset($dataProcessor['id']);
+    unset($dataProcessor['status']);
+    unset($dataProcessor['source_file']);
+
+    $sources = civicrm_api3('DataProcessorSource', 'get', array('data_processor_id' => $data_processor_id, 'options' => array('limit' => 0)));
+    $dataProcessor['data_sources'] = array();
+    foreach($sources['values'] as $i => $datasource) {
+      unset($datasource['id']);
+      unset($datasource['data_processor_id']);
+      $dataProcessor['data_sources'][] = $datasource;
+    }
+    $filters = civicrm_api3('DataProcessorFilter', 'get', array('data_processor_id' => $data_processor_id, 'options' => array('limit' => 0)));
+    $dataProcessor['filters']  = array();
+    foreach($filters['values'] as $i => $filter) {
+      unset($filter['id']);
+      unset($filter['data_processor_id']);
+      $dataProcessor['filters'][] = $filter;
+    }
+    $fields = civicrm_api3('DataProcessorField', 'get', array('data_processor_id' => $data_processor_id, 'options' => array('limit' => 0)));
+    $dataProcessor['fields'] = array();
+    foreach($fields['values'] as $i => $field) {
+      unset($field['id']);
+      unset($field['data_processor_id']);
+      $dataProcessor['fields'][] = $field;
+    }
+    $outputs = $outputs = civicrm_api3('DataProcessorOutput', 'get', array('data_processor_id' => $data_processor_id, 'options' => array('limit' => 0)));
+    $dataProcessor['outputs'] = array();
+    foreach($outputs['values'] as $i => $output) {
+      unset($output['id']);
+      unset($output['data_processor_id']);
+      $dataProcessor['outputs'][] = $output;
+    }
+
+    $eventData['data_processor'] = &$dataProcessor;
+    $event = \Civi\Core\Event\GenericHookEvent::create($eventData);
+    \Civi::dispatcher()->dispatch('hook_civicrm_dataprocessor_export', $event);
+
+    return $dataProcessor;
+  }
+
+  public static function import($data, $filename, $overWriteInDatabase=false) {
     $new_status = null;
     $new_id = null;
-
-    CRM_Dataprocessor_BAO_DataProcessor::setDataProcessorToImportingState($data['name']);
+    $data_processor_id = null;
+    $status = null;
+    try {
+      $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', ['name' => $data['name']]);
+      $data_processor_id = $dataProcessor['id'];
+      $status = $dataProcessor['status'] ? $dataProcessor['status'] : CRM_Dataprocessor_Status::STATUS_IN_DATABASE;
+    } catch (Exception $e) {
+      // Do nothing
+    }
 
     switch ($status) {
-      case CRM_Dataprocessor_DAO_DataProcessor::STATUS_IN_DATABASE:
+      case CRM_Dataprocessor_Status::STATUS_IN_DATABASE:
         // Update to overriden
-        CRM_Dataprocessor_BAO_DataProcessor::setStatusAndSourceFile($data['name'], CRM_Dataprocessor_DAO_DataProcessor::STATUS_OVERRIDDEN, $filename);
-        $new_id = $data_processor_id;
-        $new_status = CRM_Dataprocessor_DAO_DataProcessor::STATUS_OVERRIDDEN;
+        if (!$overWriteInDatabase) {
+          civicrm_api3('DataProcessor', 'create', array(
+            'id' => $data_processor_id,
+            'status' => CRM_Dataprocessor_Status::STATUS_OVERRIDDEN,
+            'source_file' => $filename,
+          ));
+          $new_id = $data_processor_id;
+          $new_status = CRM_Dataprocessor_Status::STATUS_OVERRIDDEN;
+        } else {
+          $new_id = self::importDataProcessor($data, $filename, $data_processor_id, CRM_Dataprocessor_Status::STATUS_IN_DATABASE);
+          $new_status = CRM_Dataprocessor_Status::STATUS_IN_DATABASE;
+        }
         break;
-      case CRM_Dataprocessor_DAO_DataProcessor::STATUS_OVERRIDDEN:
-        $new_id = $data_processor_id;
-        $new_status = CRM_Dataprocessor_DAO_DataProcessor::STATUS_OVERRIDDEN;
+      case CRM_Dataprocessor_Status::STATUS_OVERRIDDEN:
+        if (!$overWriteInDatabase) {
+          $new_id = $data_processor_id;
+          $new_status = CRM_Dataprocessor_Status::STATUS_OVERRIDDEN;
+        } else {
+          $new_id = self::importDataProcessor($data, $filename, $data_processor_id, CRM_Dataprocessor_Status::STATUS_OVERRIDDEN);
+          $new_status = CRM_Dataprocessor_Status::STATUS_OVERRIDDEN;
+        }
         break;
       default:
-        $new_id = self::importDataProcessor($data, $filename, $data_processor_id);
-        $new_status = CRM_Dataprocessor_DAO_DataProcessor::STATUS_IN_CODE;
+        if (!$overWriteInDatabase) {
+          $new_id = self::importDataProcessor($data, $filename, $data_processor_id, CRM_Dataprocessor_Status::STATUS_IN_CODE);
+          $new_status = CRM_Dataprocessor_Status::STATUS_IN_CODE;
+        } else {
+          $new_id = self::importDataProcessor($data, $filename, $data_processor_id, CRM_Dataprocessor_Status::STATUS_OVERRIDDEN);
+          $new_status = CRM_Dataprocessor_Status::STATUS_OVERRIDDEN;
+        }
         break;
     }
 
@@ -52,10 +127,12 @@ class CRM_Dataprocessor_Utils_Importer {
    * @return mixed
    * @throws \Exception
    */
-  public static function importDataProcessor($data, $filename, $data_processor_id) {
+  public static function importDataProcessor($data, $filename, $data_processor_id, $status) {
     $params = $data;
     unset($params['data_sources']);
     unset($params['outputs']);
+    unset($params['fields']);
+    unset($params['filters']);
     if ($data_processor_id) {
       $params['id'] = $data_processor_id;
     }
@@ -65,37 +142,42 @@ class CRM_Dataprocessor_Utils_Importer {
     if (!isset($params['storage_configuration'])) {
       $params['storage_configuration'] = array();
     }
-    $params['status'] = CRM_Dataprocessor_DAO_DataProcessor::STATUS_IN_CODE;
-    $params['source_file'] = $filename;
-    CRM_Dataprocessor_BAO_DataProcessor::setDataProcessorToImportingState($params['name']);
-    $result = CRM_Dataprocessor_BAO_DataProcessor::add($params);
+    $params['status'] = $status;
+    $params['source_file'] = $filename ? $filename : null;
+    $result = civicrm_api3('DataProcessor', 'create', $params);
     $id = $result['id'];
 
     // Clear all existing data sources and outputs
-    CRM_Dataprocessor_BAO_Source::deleteWithDataProcessorId($id);
-    CRM_Dataprocessor_BAO_Filter::deleteWithDataProcessorId($id);
-    CRM_Dataprocessor_BAO_Field::deleteWithDataProcessorId($id);
-    CRM_Dataprocessor_BAO_Output::deleteWithDataProcessorId($id);
+    CRM_Dataprocessor_BAO_DataProcessorSource::deleteWithDataProcessorId($id);
+    CRM_Dataprocessor_BAO_DataProcessorFilter::deleteWithDataProcessorId($id);
+    CRM_Dataprocessor_BAO_DataProcessorField::deleteWithDataProcessorId($id);
+    CRM_Dataprocessor_BAO_DataProcessorOutput::deleteWithDataProcessorId($id);
 
     foreach($data['data_sources'] as $data_source) {
       $params = $data_source;
       $params['data_processor_id'] = $id;
-      $result = CRM_Dataprocessor_BAO_Source::add($params);
+      $params['debug'] = 1;
+      var_dump($params);
+      try {
+        civicrm_api3('DataProcessorSource', 'create', $params);
+      } catch (\CiviCRM_API3_Exception $e) {
+        echo $e->getTraceAsString(); exit();
+      }
     }
     foreach($data['filters'] as $filter) {
       $params = $filter;
       $params['data_processor_id'] = $id;
-      $result = CRM_Dataprocessor_BAO_Filter::add($params);
+      civicrm_api3('DataProcessorFilter', 'create', $params);
     }
     foreach($data['fields'] as $field) {
       $params = $field;
       $params['data_processor_id'] = $id;
-      $result = CRM_Dataprocessor_BAO_Field::add($params);
+      civicrm_api3('DataProcessorField', 'create', $params);
     }
     foreach($data['outputs'] as $output) {
       $params = $output;
       $params['data_processor_id'] = $id;
-      $result = CRM_Dataprocessor_BAO_Output::add($params);
+      civicrm_api3('DataProcessorOutput', 'create', $params);
     }
 
     return $id;
diff --git a/CRM/DataprocessorOutputExport/CSV.php b/CRM/DataprocessorOutputExport/CSV.php
index 68a6d68742d4263f157ab922756806ee881a5b51..32cadfc10d27645a31a0b0c77191333185cc82b7 100644
--- a/CRM/DataprocessorOutputExport/CSV.php
+++ b/CRM/DataprocessorOutputExport/CSV.php
@@ -10,20 +10,52 @@ use CRM_Dataprocessor_ExtensionUtil as E;
 
 class CRM_DataprocessorOutputExport_CSV implements ExportOutputInterface {
 
-  const MAX_DIRECT_SIZE = 500;
+  const MAX_DIRECT_SIZE = 1;
 
-  const RECORDS_PER_JOB = 250;
+  const RECORDS_PER_JOB = 1;
 
   /**
-   * Return the url to a configuration page.
-   * Or return false when no configuration page exists.
+   * Returns true when this filter has additional configuration
    *
-   * @return string|false
+   * @return bool
+   */
+  public function hasConfiguration() {
+    return false;
+  }
+
+  /**
+   * When this filter type has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param array $filter
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $output=array()) {
+
+  }
+
+  /**
+   * When this filter type has configuration specify the template file name
+   * for the configuration form.
+   *
+   * @return false|string
    */
-  public function getConfigurationUrl() {
+  public function getConfigurationTemplateFileName() {
     return false;
   }
 
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @param array $output
+   * @return array
+   */
+  public function processConfiguration($submittedValues, &$output) {
+    return array();
+  }
+
   /**
    * Returns the mime type of the export file.
    *
@@ -58,25 +90,26 @@ class CRM_DataprocessorOutputExport_CSV implements ExportOutputInterface {
   /**
    * Download export
    *
-   * @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor
-   * @param array $dataProcessorBAO
+   * @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessorClass
+   * @param array $dataProcessor
    * @param array $outputBAO
    * @param array $formValues
    * @param string $sortFieldName
    * @param string $sortDirection
    * @return string
    */
-  public function downloadExport(\Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor, $dataProcessorBAO, $outputBAO, $formValues, $sortFieldName = null, $sortDirection = 'ASC') {
+  public function downloadExport(\Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessorClass, $dataProcessor, $outputBAO, $formValues, $sortFieldName = null, $sortDirection = 'ASC') {
     if ($dataProcessor->getDataFlow()->recordCount() > self::MAX_DIRECT_SIZE) {
-      $this->startBatchJob($dataProcessor, $dataProcessorBAO, $outputBAO, $formValues, $sortFieldName, $sortDirection);
+      $this->startBatchJob($dataProcessorClass, $dataProcessor, $outputBAO, $formValues, $sortFieldName, $sortDirection);
     } else {
-      $this->doDirectDownload($dataProcessor, $dataProcessorBAO, $outputBAO, $sortFieldName, $sortDirection);
+      $this->doDirectDownload($dataProcessorClass, $dataProcessor, $outputBAO, $sortFieldName, $sortDirection);
     }
   }
 
-  protected function doDirectDownload(\Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor, $dataProcessorBAO, $outputBAO, $sortFieldName = null, $sortDirection = 'ASC') {
-    $filename = date('Ymdhis').'_'.$dataProcessorBAO['id'].'_'.$outputBAO['id'].'_'.CRM_Core_Session::getLoggedInContactID().'_'.$dataProcessorBAO['name'].'.csv';
-    $download_name = date('Ymdhis').'_'.$dataProcessorBAO['name'].'.csv';
+  protected function doDirectDownload(\Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessorClass, $dataProcessor, $outputBAO, $sortFieldName = null, $sortDirection = 'ASC') {
+    $filename = date('Ymdhis').'_'.$dataProcessor['id'].'_'.$outputBAO['id'].'_'.CRM_Core_Session::getLoggedInContactID().'_'.$dataProcessor['name'].'.csv';
+    $download_name = date('Ymdhis').'_'.$dataProcessor['name'].'.csv';
+
     $basePath = CRM_Core_Config::singleton()->templateCompileDir . 'dataprocessor_export_csv';
     CRM_Utils_File::createDir($basePath);
     CRM_Utils_File::restrictAccess($basePath.'/');
@@ -86,8 +119,8 @@ class CRM_DataprocessorOutputExport_CSV implements ExportOutputInterface {
       $dataProcessor->getDataFlow()->addSort($sortFieldName, $sortDirection);
     }
 
-    self::createHeaderLine($path, $dataProcessor);
-    self::exportDataProcessor($path, $dataProcessor);
+    self::createHeaderLine($path, $dataProcessorClass);
+    self::exportDataProcessor($path, $dataProcessorClass);
 
     $mimeType = CRM_Utils_Request::retrieveValue('mime-type', 'String', '', FALSE);
 
@@ -110,10 +143,11 @@ class CRM_DataprocessorOutputExport_CSV implements ExportOutputInterface {
     );
   }
 
-  protected function startBatchJob(\Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor, $dataProcessorBAO, $outputBAO, $formValues, $sortFieldName = null, $sortDirection = 'ASC') {
+
+  protected function startBatchJob(\Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessorClass, $dataProcessor, $outputBAO, $formValues, $sortFieldName = null, $sortDirection = 'ASC') {
     $session = CRM_Core_Session::singleton();
 
-    $name = date('Ymdhis').'_'.$dataProcessorBAO['id'].'_'.$outputBAO['id'].'_'.CRM_Core_Session::getLoggedInContactID().'_'.$dataProcessorBAO['name'];
+    $name = date('Ymdhis').'_'.$dataProcessor['id'].'_'.$outputBAO['id'].'_'.CRM_Core_Session::getLoggedInContactID().'_'.$dataProcessor['name'];
 
     $queue = CRM_Queue_Service::singleton()->create(array(
       'type' => 'Sql',
@@ -126,9 +160,9 @@ class CRM_DataprocessorOutputExport_CSV implements ExportOutputInterface {
     CRM_Utils_File::restrictAccess($basePath.'/');
     $filename = $basePath.'/'. $name.'.csv';
 
-    self::createHeaderLine($filename, $dataProcessor);
+    self::createHeaderLine($filename, $dataProcessorClass);
 
-    $count = $dataProcessor->getDataFlow()->recordCount();
+    $count = $dataProcessorClass->getDataFlow()->recordCount();
     $recordsPerJob = self::RECORDS_PER_JOB;
     for($i=0; $i < $count; $i = $i + $recordsPerJob) {
       $title = E::ts('Exporting records %1/%2', array(
@@ -142,7 +176,7 @@ class CRM_DataprocessorOutputExport_CSV implements ExportOutputInterface {
           'CRM_DataprocessorOutputExport_CSV',
           'exportBatch'
         ), //call back method
-        array($filename,$formValues, $dataProcessorBAO['id'], $i, $recordsPerJob, $sortFieldName, $sortDirection), //parameters,
+        array($filename,$formValues, $dataProcessor['id'], $i, $recordsPerJob, $sortFieldName, $sortDirection), //parameters,
         $title
       );
       //now add this task to the queue
@@ -190,14 +224,15 @@ class CRM_DataprocessorOutputExport_CSV implements ExportOutputInterface {
   }
 
   public static function exportBatch(CRM_Queue_TaskContext $ctx, $filename, $params, $dataProcessorId, $offset, $limit, $sortFieldName = null, $sortDirection = 'ASC') {
-    $dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getDataProcessorById($dataProcessorId);
+    $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $dataProcessorId));
+    $dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($dataProcessor);
     CRM_Dataprocessor_Form_Output_AbstractUIOutputForm::applyFilters($dataProcessor, $params);
     if ($sortFieldName) {
-      $dataProcessor->getDataFlow()->addSort($sortFieldName, $sortDirection);
+      $dataProcessorClass->getDataFlow()->addSort($sortFieldName, $sortDirection);
     }
-    $dataProcessor->getDataFlow()->setOffset($offset);
-    $dataProcessor->getDataFlow()->setLimit($limit);
-    self::exportDataProcessor($filename, $dataProcessor);
+    $dataProcessorClass->getDataFlow()->setOffset($offset);
+    $dataProcessorClass->getDataFlow()->setLimit($limit);
+    self::exportDataProcessor($filename, $dataProcessorClass);
     return TRUE;
   }
 
diff --git a/CRM/DataprocessorOutputExport/Page/Download.php b/CRM/DataprocessorOutputExport/Page/Download.php
index 33a6a31d4e047de76bbd676c4de75e7414a5765f..60dc29759a9f6a07e9522e53acd11a203268dbc8 100644
--- a/CRM/DataprocessorOutputExport/Page/Download.php
+++ b/CRM/DataprocessorOutputExport/Page/Download.php
@@ -31,9 +31,9 @@ class CRM_DataprocessorOutputExport_Page_Download extends CRM_Core_Page {
     list($prefix, $dataProcessorId, $outputId, $userId, $download_name) = explode("_", $fileName, 5);
     $download_name = $prefix.'_'.$download_name;
 
-    $data_processors = CRM_Dataprocessor_BAO_DataProcessor::getValues(array('id' => $dataProcessorId));
-    $outputs = CRM_Dataprocessor_BAO_Output::getValues(array('id' => $outputId));
-    $outputClass = $factory->getOutputByName($outputs[$outputId]['type']);
+    $data_processor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $dataProcessorId));
+    $output = civicrm_api3("DataProcessorOutput", "getsingle", array('id' => $outputId));
+    $outputClass = $factory->getOutputByName($output['type']);
     if (!$outputClass instanceof \Civi\DataProcessor\Output\ExportOutputInterface) {
       CRM_Core_Error::statusBounce("Malformed filename");
     } elseif ($userId != CRM_Core_Session::getLoggedInContactID()) {
diff --git a/CRM/DataprocessorSearch/ActivitySearch.php b/CRM/DataprocessorSearch/ActivitySearch.php
index bb22bd3124d91300a0e623e39d83b0a615a8db74..aa78f8edf2ea011fc3c1e51959a8eb65734ebc95 100644
--- a/CRM/DataprocessorSearch/ActivitySearch.php
+++ b/CRM/DataprocessorSearch/ActivitySearch.php
@@ -6,8 +6,120 @@
 
 use Civi\DataProcessor\Output\UIOutputInterface;
 
+use CRM_Dataprocessor_ExtensionUtil as E;
+
 class CRM_DataprocessorSearch_ActivitySearch implements UIOutputInterface {
 
+  /**
+   * Returns true when this filter has additional configuration
+   *
+   * @return bool
+   */
+  public function hasConfiguration() {
+    return true;
+  }
+
+  /**
+   * When this filter type has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param array $filter
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $output=array()) {
+    $navigation = CRM_Dataprocessor_Utils_Navigation::singleton();
+    $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $output['data_processor_id']));
+    $dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($dataProcessor);
+    $fields = array();
+    foreach($dataProcessorClass->getDataFlow()->getOutputFieldHandlers() as $outputFieldHandler) {
+      $field = $outputFieldHandler->getOutputFieldSpecification();
+      $fields[$field->alias] = $field->title;
+    }
+
+    $form->add('text', 'title', E::ts('Title'), true);
+
+    $form->add('select','permission', E::ts('Permission'), \CRM_Core_Permission::basicPermissions(), true, array(
+      'style' => 'min-width:250px',
+      'class' => 'crm-select2 huge',
+      'placeholder' => E::ts('- select -'),
+    ));
+    $form->add('select', 'activity_id_field', E::ts('Activity ID field'), $fields, true, array(
+      'style' => 'min-width:250px',
+      'class' => 'crm-select2 huge',
+      'placeholder' => E::ts('- select -'),
+    ));
+    $form->add('select', 'hide_id_field', E::ts('Show Activity ID field'), array(0=>'Activity ID is Visible', 1=> 'Activity ID is hidden'));
+
+    $form->add('wysiwyg', 'help_text', E::ts('Help text for this search'), array('rows' => 6, 'cols' => 80));
+
+    // navigation field
+    $navigationOptions = $navigation->getNavigationOptions();
+    if (isset($output['configuration']['navigation_id'])) {
+      $navigationPath = $navigation->getNavigationPathById($output['configuration']['navigation_id']);
+      unset($navigationOptions[$navigationPath]);
+    }
+    $form->add('select', 'navigation_parent_path', ts('Parent Menu'), array('' => ts('- select -')) + $navigationOptions, true);
+
+    $defaults = array();
+    if ($output) {
+      if (isset($output['permission'])) {
+        $defaults['permission'] = $output['permission'];
+      }
+      if (isset($output['configuration']) && is_array($output['configuration'])) {
+        if (isset($output['configuration']['activity_id_field'])) {
+          $defaults['activity_id_field'] = $output['configuration']['activity_id_field'];
+        }
+        if (isset($output['configuration']['navigation_id'])) {
+          $defaults['navigation_parent_path'] = $navigation->getNavigationParentPathById($output['configuration']['navigation_id']);
+        }
+        if (isset($output['configuration']['title'])) {
+          $defaults['title'] = $output['configuration']['title'];
+        }
+        if (isset($output['configuration']['hide_id_field'])) {
+          $defaults['hide_id_field'] = $output['configuration']['hide_id_field'];
+        }
+        if (isset($output['configuration']['help_text'])) {
+          $defaults['help_text'] = $output['configuration']['help_text'];
+        }
+      }
+    }
+    if (!isset($defaults['permission'])) {
+      $defaults['permission'] = 'access CiviCRM';
+    }
+    if (empty($defaults['title'])) {
+      $defaults['title'] = civicrm_api3('DataProcessor', 'getvalue', array('id' => $output['data_processor_id'], 'return' => 'title'));
+    }
+    $form->setDefaults($defaults);
+  }
+
+  /**
+   * When this filter type has configuration specify the template file name
+   * for the configuration form.
+   *
+   * @return false|string
+   */
+  public function getConfigurationTemplateFileName() {
+    return "CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.tpl";
+  }
+
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @param array $output
+   * @return array
+   */
+  public function processConfiguration($submittedValues, &$output) {
+    $output['permission'] = $submittedValues['permission'];
+    $configuration['title'] = $submittedValues['title'];
+    $configuration['activity_id_field'] = $submittedValues['activity_id_field'];
+    $configuration['navigation_parent_path'] = $submittedValues['navigation_parent_path'];
+    $configuration['hide_id_field'] = $submittedValues['hide_id_field'];
+    $configuration['help_text'] = $submittedValues['help_text'];
+    return $configuration;
+  }
+
   /**
    * Returns the url for the page/form this output will show to the user
    *
@@ -50,16 +162,6 @@ class CRM_DataprocessorSearch_ActivitySearch implements UIOutputInterface {
     return 'CRM_DataprocessorSearch_Controller_ActivitySearch';
   }
 
-  /**
-   * Return the url to a configuration page.
-   * Or return false when no configuration page exists.
-   *
-   * @return string|false
-   */
-  public function getConfigurationUrl() {
-    return 'civicrm/dataprocessor/form/output/activity_search';
-  }
-
   /**
    * Checks whether the current user has access to this output
    *
diff --git a/CRM/DataprocessorSearch/ContactSearch.php b/CRM/DataprocessorSearch/ContactSearch.php
index 9c6bbc870c285e7041ad3c5facce2a51664cfb4f..7e34a5da2db94eda29b953fb17273820df10b485 100644
--- a/CRM/DataprocessorSearch/ContactSearch.php
+++ b/CRM/DataprocessorSearch/ContactSearch.php
@@ -5,17 +5,118 @@
  */
 
 use Civi\DataProcessor\Output\UIOutputInterface;
+use CRM_Dataprocessor_ExtensionUtil as E;
 
 class CRM_DataprocessorSearch_ContactSearch implements UIOutputInterface {
 
   /**
-   * Return the url to a configuration page.
-   * Or return false when no configuration page exists.
+   * Returns true when this filter has additional configuration
    *
-   * @return string|false
+   * @return bool
+   */
+  public function hasConfiguration() {
+    return true;
+  }
+
+  /**
+   * When this filter type has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param array $filter
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $output=array()) {
+    $navigation = CRM_Dataprocessor_Utils_Navigation::singleton();
+    $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $output['data_processor_id']));
+    $dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($dataProcessor);
+    $fields = array();
+    foreach($dataProcessorClass->getDataFlow()->getOutputFieldHandlers() as $outputFieldHandler) {
+      $field = $outputFieldHandler->getOutputFieldSpecification();
+      $fields[$field->alias] = $field->title;
+    }
+
+    $form->add('text', 'title', E::ts('Title'), true);
+
+    $form->add('select','permission', E::ts('Permission'), \CRM_Core_Permission::basicPermissions(), true, array(
+      'style' => 'min-width:250px',
+      'class' => 'crm-select2 huge',
+      'placeholder' => E::ts('- select -'),
+    ));
+    $form->add('select', 'contact_id_field', E::ts('Contact ID field'), $fields, true, array(
+      'style' => 'min-width:250px',
+      'class' => 'crm-select2 huge',
+      'placeholder' => E::ts('- select -'),
+    ));
+    $form->add('select', 'hide_id_field', E::ts('Show Contact ID field'), array(0=>'Contact ID is Visible', 1=> 'Contact ID is hidden'));
+
+    $form->add('wysiwyg', 'help_text', E::ts('Help text for this search'), array('rows' => 6, 'cols' => 80));
+
+    // navigation field
+    $navigationOptions = $navigation->getNavigationOptions();
+    if (isset($output['configuration']['navigation_id'])) {
+      $navigationPath = $navigation->getNavigationPathById($output['configuration']['navigation_id']);
+      unset($navigationOptions[$navigationPath]);
+    }
+    $form->add('select', 'navigation_parent_path', ts('Parent Menu'), array('' => ts('- select -')) + $navigationOptions, true);
+
+    $defaults = array();
+    if ($output) {
+      if (isset($output['permission'])) {
+        $defaults['permission'] = $output['permission'];
+      }
+      if (isset($output['configuration']) && is_array($output['configuration'])) {
+        if (isset($output['configuration']['contact_id_field'])) {
+          $defaults['contact_id_field'] = $output['configuration']['contact_id_field'];
+        }
+        if (isset($output['configuration']['navigation_id'])) {
+          $defaults['navigation_parent_path'] = $navigation->getNavigationParentPathById($output['configuration']['navigation_id']);
+        }
+        if (isset($output['configuration']['title'])) {
+          $defaults['title'] = $output['configuration']['title'];
+        }
+        if (isset($output['configuration']['hide_id_field'])) {
+          $defaults['hide_id_field'] = $output['configuration']['hide_id_field'];
+        }
+        if (isset($output['configuration']['help_text'])) {
+          $defaults['help_text'] = $output['configuration']['help_text'];
+        }
+      }
+    }
+    if (!isset($defaults['permission'])) {
+      $defaults['permission'] = 'access CiviCRM';
+    }
+    if (empty($defaults['title'])) {
+      $defaults['title'] = civicrm_api3('DataProcessor', 'getvalue', array('id' => $output['data_processor_id'], 'return' => 'title'));
+    }
+    $form->setDefaults($defaults);
+  }
+
+  /**
+   * When this filter type has configuration specify the template file name
+   * for the configuration form.
+   *
+   * @return false|string
+   */
+  public function getConfigurationTemplateFileName() {
+    return "CRM/DataprocessorSearch/Form/OutputConfiguration/ContactSearch.tpl";
+  }
+
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @param array $output
+   * @return array
    */
-  public function getConfigurationUrl() {
-    return 'civicrm/dataprocessor/form/output/contact_search';
+  public function processConfiguration($submittedValues, &$output) {
+    $output['permission'] = $submittedValues['permission'];
+    $configuration['title'] = $submittedValues['title'];
+    $configuration['contact_id_field'] = $submittedValues['contact_id_field'];
+    $configuration['navigation_parent_path'] = $submittedValues['navigation_parent_path'];
+    $configuration['hide_id_field'] = $submittedValues['hide_id_field'];
+    $configuration['help_text'] = $submittedValues['help_text'];
+    return $configuration;
   }
 
   /**
diff --git a/CRM/DataprocessorSearch/Form/AbstractSearch.php b/CRM/DataprocessorSearch/Form/AbstractSearch.php
index 4251642805abd59a23cce6fce9f6c49ca0944a54..95d4a391db0700f73ae5863466607ffc80cf0021 100644
--- a/CRM/DataprocessorSearch/Form/AbstractSearch.php
+++ b/CRM/DataprocessorSearch/Form/AbstractSearch.php
@@ -170,7 +170,7 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce
 
   protected function runExport($export_id) {
     $factory = dataprocessor_get_factory();
-    self::applyFilters($this->dataProcessor, $this->_formValues);
+    self::applyFilters($this->dataProcessorClass, $this->_formValues);
 
     // Set the sort
     $sortDirection = 'ASC';
@@ -183,11 +183,10 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce
       $sortFieldName = $sortField['name'];
     }
 
-    $outputs = CRM_Dataprocessor_BAO_Output::getValues(array('id' => $export_id));
-    $output = $outputs[$export_id];
+    $output = civicrm_api3("DataProcessorOutput", "getsingle", array('id' => $export_id));
     $outputClass = $factory->getOutputByName($output['type']);
     if ($outputClass instanceof \Civi\DataProcessor\Output\ExportOutputInterface) {
-      $outputClass->downloadExport($this->dataProcessor, $this->dataProcessorBAO, $output, $this->_formValues, $sortFieldName, $sortDirection);
+      $outputClass->downloadExport($this->dataProcessorClass, $this->dataProcessor, $output, $this->_formValues, $sortFieldName, $sortDirection);
     }
   }
 
@@ -208,9 +207,9 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce
     $this->assign('id_field', $id_field);
 
     $offset = ($pageId - 1) * $limit;
-    $this->dataProcessor->getDataFlow()->setLimit($limit);
-    $this->dataProcessor->getDataFlow()->setOffset($offset);
-    self::applyFilters($this->dataProcessor, $this->_formValues);
+    $this->dataProcessorClass->getDataFlow()->setLimit($limit);
+    $this->dataProcessorClass->getDataFlow()->setOffset($offset);
+    self::applyFilters($this->dataProcessorClass, $this->_formValues);
 
     // Set the sort
     $sortDirection = 'ASC';
@@ -219,18 +218,18 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce
       if ($this->sort->getCurrentSortDirection() == CRM_Utils_Sort::DESCENDING) {
         $sortDirection = 'DESC';
       }
-      $this->dataProcessor->getDataFlow()->addSort($sortField['name'], $sortDirection);
+      $this->dataProcessorClass->getDataFlow()->addSort($sortField['name'], $sortDirection);
     }
 
     $pagerParams = $this->getPagerParams();
-    $pagerParams['total'] = $this->dataProcessor->getDataFlow()->recordCount();
+    $pagerParams['total'] = $this->dataProcessorClass->getDataFlow()->recordCount();
     $pagerParams['pageID'] = $pageId;
     $this->pager = new CRM_Utils_Pager($pagerParams);
     $this->assign('pager', $this->pager);
 
     $i=0;
     try {
-      while($record = $this->dataProcessor->getDataFlow()->nextRecord()) {
+      while($record = $this->dataProcessorClass->getDataFlow()->nextRecord()) {
         $i ++;
         $row = array();
         $row['id'] = $record[$id_field]->formattedValue;
@@ -262,7 +261,7 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce
 
     $this->addElement('checkbox', 'toggleSelect', NULL, NULL, ['class' => 'select-rows']);
     $this->assign('rows', $rows);
-    $this->assign('debug_info', $this->dataProcessor->getDataFlow()->getDebugInformation());
+    $this->assign('debug_info', $this->dataProcessorClass->getDataFlow()->getDebugInformation());
     if ($this->usePrevNextCache()) {
       $cacheKey = "civicrm search {$this->controller->_key}";
       CRM_DataprocessorSearch_Utils_PrevNextCache::fillWithArray($cacheKey, $prevnextData);
@@ -283,7 +282,7 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce
     $idFieldVisible = $this->isIdFieldVisible();
     $columnHeaders = array();
     $sortColumnNr = 1;
-    foreach($this->dataProcessor->getDataFlow()->getOutputFieldHandlers() as $outputFieldHandler) {
+    foreach($this->dataProcessorClass->getDataFlow()->getOutputFieldHandlers() as $outputFieldHandler) {
       $field = $outputFieldHandler->getOutputFieldSpecification();
       $hiddenField = true;
       if ($field->alias != $id_field) {
@@ -324,18 +323,18 @@ abstract class CRM_DataprocessorSearch_Form_AbstractSearch extends CRM_Dataproce
    */
   protected function addExportOutputs() {
     $factory = dataprocessor_get_factory();
-    $outputs = CRM_Dataprocessor_BAO_Output::getValues(array('data_processor_id' => $this->dataProcessorId));
+    $outputs = civicrm_api3('DataProcessorOutput', 'get', array('data_processor_id' => $this->dataProcessorId, 'options' => array('limit' => 0)));
     $otherOutputs = array();
-    foreach($outputs as $output) {
+    foreach($outputs['values'] as $output) {
       if ($output['id'] == $this->dataProcessorOutput['id']) {
         continue;
       }
-      $outputClass = $factory->getOutputByName(($output['type']));
+      $outputClass = $factory->getOutputByName($output['type']);
       if ($outputClass instanceof \Civi\DataProcessor\Output\ExportOutputInterface) {
         $otherOutput = array();
-        $otherOutput['title'] = $outputClass->getTitleForExport($output, $this->dataProcessorBAO);
+        $otherOutput['title'] = $outputClass->getTitleForExport($output, $this->dataProcessor);
         $otherOutput['url'] = $this->currentUrl.'&export_id='.$output['id'];
-        $otherOutput['icon'] = $outputClass->getExportFileIcon($output, $this->dataProcessorBAO);
+        $otherOutput['icon'] = $outputClass->getExportFileIcon($output, $this->dataProcessor);
         $otherOutputs[] = $otherOutput;
       }
     }
diff --git a/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.php b/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.php
deleted file mode 100644
index cd422d9e9a03a239fe0d4beac9cb05a8ab50cd1c..0000000000000000000000000000000000000000
--- a/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * Form controller class
- *
- * @see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference
- */
-class CRM_DataprocessorSearch_Form_OutputConfiguration_ActivitySearch extends CRM_Dataprocessor_Form_Output_AbstractOutputForm {
-
-  /**
-   * @var CRM_Dataprocessor_Utils_Navigation
-   */
-  protected $navigation;
-
-  public function preProcess() {
-    parent::preProcess();
-    $this->navigation = CRM_Dataprocessor_Utils_Navigation::singleton();
-  }
-
-  public function buildQuickForm() {
-    parent::buildQuickForm();
-
-    $dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getDataProcessorById($this->dataProcessorId);
-    $fields = array();
-    foreach($dataProcessor->getDataFlow()->getOutputFieldHandlers() as $outputFieldHandler) {
-      $field = $outputFieldHandler->getOutputFieldSpecification();
-      $fields[$field->alias] = $field->title;
-    }
-
-    $this->add('text', 'title', E::ts('Title'), true);
-
-    $this->add('select','permission', E::ts('Permission'), CRM_Core_Permission::basicPermissions(), true, array(
-      'style' => 'min-width:250px',
-      'class' => 'crm-select2 huge',
-      'placeholder' => E::ts('- select -'),
-    ));
-    $this->add('select', 'activity_id_field', E::ts('Activity ID field'), $fields, true, array(
-      'style' => 'min-width:250px',
-      'class' => 'crm-select2 huge',
-      'placeholder' => E::ts('- select -'),
-    ));
-    $this->add('select', 'hide_id_field', E::ts('Show Activity ID field'), array(0=>'Activity ID is Visible', 1=> 'Activity ID is hidden'));
-
-    $this->add('wysiwyg', 'help_text', E::ts('Help text for this search'), array('rows' => 6, 'cols' => 80));
-
-    // navigation field
-    $navigationOptions = $this->navigation->getNavigationOptions();
-    if (isset($this->output['configuration']['navigation_id'])) {
-      $navigationPath = $this->navigation->getNavigationPathById($this->output['configuration']['navigation_id']);
-      unset($navigationOptions[$navigationPath]);
-    }
-    $this->add('select', 'navigation_parent_path', ts('Parent Menu'), array('' => ts('- select -')) + $navigationOptions, true);
-  }
-
-  function setDefaultValues() {
-    $dataProcessors = CRM_Dataprocessor_BAO_DataProcessor::getValues(array('id' => $this->dataProcessorId));
-    $dataProcessor = $dataProcessors[$this->dataProcessorId];
-
-    $defaults = parent::setDefaultValues();
-    if ($this->output) {
-      if (isset($this->output['permission'])) {
-        $defaults['permission'] = $this->output['permission'];
-      }
-      if (isset($this->output['configuration']) && is_array($this->output['configuration'])) {
-        if (isset($this->output['configuration']['activity_id_field'])) {
-          $defaults['activity_id_field'] = $this->output['configuration']['activity_id_field'];
-        }
-        if (isset($this->output['configuration']['navigation_id'])) {
-          $defaults['navigation_parent_path'] = $this->navigation->getNavigationParentPathById($this->output['configuration']['navigation_id']);
-        }
-        if (isset($this->output['configuration']['title'])) {
-          $defaults['title'] = $this->output['configuration']['title'];
-        }
-        if (isset($this->output['configuration']['hide_id_field'])) {
-          $defaults['hide_id_field'] = $this->output['configuration']['hide_id_field'];
-        }
-        if (isset($this->output['configuration']['help_text'])) {
-          $defaults['help_text'] = $this->output['configuration']['help_text'];
-        }
-      }
-    }
-    if (!isset($defaults['permission'])) {
-      $defaults['permission'] = 'access CiviCRM';
-    }
-    if (empty($defaults['title'])) {
-      $defaults['title'] = $dataProcessor['title'];
-    }
-
-    return $defaults;
-  }
-
-  public function postProcess() {
-    $values = $this->exportValues();
-
-    $session = CRM_Core_Session::singleton();
-    $redirectUrl = $session->readUserContext();
-
-    $params['id'] = $this->id;
-    $params['permission'] = $values['permission'];
-    $params['configuration']['title'] = $values['title'];
-    $params['configuration']['activity_id_field'] = $values['activity_id_field'];
-    $params['configuration']['navigation_parent_path'] = $values['navigation_parent_path'];
-    $params['configuration']['hide_id_field'] = $values['hide_id_field'];
-    $params['configuration']['help_text'] = $values['help_text'];
-
-    CRM_Dataprocessor_BAO_Output::add($params);
-
-    CRM_Utils_System::redirect($redirectUrl);
-    parent::postProcess();
-  }
-
-}
\ No newline at end of file
diff --git a/CRM/DataprocessorSearch/Form/OutputConfiguration/ContactSearch.php b/CRM/DataprocessorSearch/Form/OutputConfiguration/ContactSearch.php
deleted file mode 100644
index 71530ee1a780b27e3677ebae9c7c572ace431821..0000000000000000000000000000000000000000
--- a/CRM/DataprocessorSearch/Form/OutputConfiguration/ContactSearch.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * Form controller class
- *
- * @see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference
- */
-class CRM_DataprocessorSearch_Form_OutputConfiguration_ContactSearch extends CRM_Dataprocessor_Form_Output_AbstractOutputForm {
-
-  /**
-   * @var CRM_Dataprocessor_Utils_Navigation
-   */
-  protected $navigation;
-
-  public function preProcess() {
-    parent::preProcess();
-    $this->navigation = CRM_Dataprocessor_Utils_Navigation::singleton();
-  }
-
-  public function buildQuickForm() {
-    parent::buildQuickForm();
-
-    $dataProcessor = CRM_Dataprocessor_BAO_DataProcessor::getDataProcessorById($this->dataProcessorId);
-    $fields = array();
-    foreach($dataProcessor->getDataFlow()->getOutputFieldHandlers() as $outputFieldHandler) {
-      $field = $outputFieldHandler->getOutputFieldSpecification();
-      $fields[$field->alias] = $field->title;
-    }
-
-    $this->add('text', 'title', E::ts('Title'), true);
-
-    $this->add('select','permission', E::ts('Permission'), CRM_Core_Permission::basicPermissions(), true, array(
-      'style' => 'min-width:250px',
-      'class' => 'crm-select2 huge',
-      'placeholder' => E::ts('- select -'),
-    ));
-    $this->add('select', 'contact_id_field', E::ts('Contact ID field'), $fields, true, array(
-      'style' => 'min-width:250px',
-      'class' => 'crm-select2 huge',
-      'placeholder' => E::ts('- select -'),
-    ));
-    $this->add('select', 'hide_id_field', E::ts('Show Contact ID field'), array(0=>'Contact ID is Visible', 1=> 'Contact ID is hidden'));
-
-    $this->add('wysiwyg', 'help_text', E::ts('Help text for this search'), array('rows' => 6, 'cols' => 80));
-
-    // navigation field
-    $navigationOptions = $this->navigation->getNavigationOptions();
-    if (isset($this->output['configuration']['navigation_id'])) {
-      $navigationPath = $this->navigation->getNavigationPathById($this->output['configuration']['navigation_id']);
-      unset($navigationOptions[$navigationPath]);
-    }
-    $this->add('select', 'navigation_parent_path', ts('Parent Menu'), array('' => ts('- select -')) + $navigationOptions, true);
-  }
-
-  function setDefaultValues() {
-    $dataProcessors = CRM_Dataprocessor_BAO_DataProcessor::getValues(array('id' => $this->dataProcessorId));
-    $dataProcessor = $dataProcessors[$this->dataProcessorId];
-
-    $defaults = parent::setDefaultValues();
-    if ($this->output) {
-      if (isset($this->output['permission'])) {
-        $defaults['permission'] = $this->output['permission'];
-      }
-      if (isset($this->output['configuration']) && is_array($this->output['configuration'])) {
-        if (isset($this->output['configuration']['contact_id_field'])) {
-          $defaults['contact_id_field'] = $this->output['configuration']['contact_id_field'];
-        }
-        if (isset($this->output['configuration']['navigation_id'])) {
-          $defaults['navigation_parent_path'] = $this->navigation->getNavigationParentPathById($this->output['configuration']['navigation_id']);
-        }
-        if (isset($this->output['configuration']['title'])) {
-          $defaults['title'] = $this->output['configuration']['title'];
-        }
-        if (isset($this->output['configuration']['hide_id_field'])) {
-          $defaults['hide_id_field'] = $this->output['configuration']['hide_id_field'];
-        }
-        if (isset($this->output['configuration']['help_text'])) {
-          $defaults['help_text'] = $this->output['configuration']['help_text'];
-        }
-      }
-    }
-    if (!isset($defaults['permission'])) {
-      $defaults['permission'] = 'access CiviCRM';
-    }
-    if (empty($defaults['title'])) {
-      $defaults['title'] = $dataProcessor['title'];
-    }
-
-    return $defaults;
-  }
-
-  public function postProcess() {
-    $values = $this->exportValues();
-
-    $session = CRM_Core_Session::singleton();
-    $redirectUrl = $session->readUserContext();
-
-    $params['id'] = $this->id;
-    $params['permission'] = $values['permission'];
-    $params['configuration']['title'] = $values['title'];
-    $params['configuration']['contact_id_field'] = $values['contact_id_field'];
-    $params['configuration']['navigation_parent_path'] = $values['navigation_parent_path'];
-    $params['configuration']['hide_id_field'] = $values['hide_id_field'];
-    $params['configuration']['help_text'] = $values['help_text'];
-
-    CRM_Dataprocessor_BAO_Output::add($params);
-
-    CRM_Utils_System::redirect($redirectUrl);
-    parent::postProcess();
-  }
-
-}
\ No newline at end of file
diff --git a/Civi/DataProcessor/DataFlow/MultipleDataFlows/JoinInterface.php b/Civi/DataProcessor/DataFlow/MultipleDataFlows/JoinInterface.php
index 7c0de65a46205652e0985668589730d2b7eb4bc8..9c2a705ea9251b660f82fed32e62772e70da8206 100644
--- a/Civi/DataProcessor/DataFlow/MultipleDataFlows/JoinInterface.php
+++ b/Civi/DataProcessor/DataFlow/MultipleDataFlows/JoinInterface.php
@@ -8,6 +8,7 @@ namespace Civi\DataProcessor\DataFlow\MultipleDataFlows;
 
 use Civi\DataProcessor\DataFlow\AbstractDataFlow;
 use Civi\DataProcessor\ProcessorType\AbstractProcessorType;
+use Civi\DataProcessor\Source\SourceInterface;
 
 interface JoinInterface{
 
@@ -50,13 +51,6 @@ interface JoinInterface{
    */
   public function setConfiguration($configuration);
 
-  /**
-   * Returns the URL for the configuration form of the join specification
-   *
-   * @return string
-   */
-  public function getConfigurationUrl();
-
   /**
    * Prepares the right data flow based on the data in the left record set.
    *
@@ -67,4 +61,41 @@ interface JoinInterface{
    */
   public function prepareRightDataFlow($left_record_set, AbstractDataFlow $rightDataFlow);
 
+  /**
+   * Returns true when this join has additional configuration
+   *
+   * @return bool
+   */
+  public function hasConfiguration();
+
+  /**
+   * When this join has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param SourceInterface $joinFromSource
+   * @param SourceInterface[] $joinableToSources
+   * @param array $joinConfiguration
+   *   The current join configuration
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, SourceInterface $joinFromSource, $joinableToSources, $joinConfiguration=array());
+
+  /**
+   * When this join has configuration specify the template file name
+   * for the configuration form.
+   *
+   * @return false|string
+   */
+  public function getConfigurationTemplateFileName();
+
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @param SourceInterface $joinFromSource
+   * @return array
+   */
+  public function processConfiguration($submittedValues, SourceInterface $joinFromSource);
+
 }
\ No newline at end of file
diff --git a/Civi/DataProcessor/DataFlow/MultipleDataFlows/SimpleJoin.php b/Civi/DataProcessor/DataFlow/MultipleDataFlows/SimpleJoin.php
index bfd5045d0f99fe4113ae1339c6ff85d3de943112..108472b6a047351cdd9dc3cbccad22a914b801fc 100644
--- a/Civi/DataProcessor/DataFlow/MultipleDataFlows/SimpleJoin.php
+++ b/Civi/DataProcessor/DataFlow/MultipleDataFlows/SimpleJoin.php
@@ -11,6 +11,9 @@ use Civi\DataProcessor\DataFlow\CombinedDataFlow\CombinedSqlDataFlow;
 use Civi\DataProcessor\DataFlow\SqlDataFlow;
 use Civi\DataProcessor\DataFlow\SqlTableDataFlow;
 use Civi\DataProcessor\ProcessorType\AbstractProcessorType;
+use Civi\DataProcessor\Source\SourceInterface;
+
+use CRM_Dataprocessor_ExtensionUtil as E;
 
 class SimpleJoin implements JoinInterface, SqlJoinInterface {
 
@@ -109,10 +112,92 @@ class SimpleJoin implements JoinInterface, SqlJoinInterface {
   }
 
   /**
-   * @return string
+   * Returns true when this join has additional configuration
+   *
+   * @return bool
+   */
+  public function hasConfiguration() {
+    return true;
+  }
+
+  /**
+   * When this join has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param SourceInterface $joinFromSource
+   * @param SourceInterface[] $joinableToSources
+   * @param array $joinConfiguration
+   *   The current join configuration
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, SourceInterface $joinFromSource, $joinableToSources, $joinConfiguration=array()) {
+    $leftFields = \CRM_Dataprocessor_Utils_DataSourceFields::getAvailableFieldsInDataSource($joinFromSource, '', '');
+    $form->add('select', 'left_field', ts('Select field'), $leftFields, true, array(
+      'style' => 'min-width:250px',
+      'class' => 'crm-select2 huge',
+      'placeholder' => E::ts('- select -'),
+    ));
+
+    $rightFields = array();
+    foreach($joinableToSources as $joinToSource) {
+      $rightFields = array_merge($rightFields, \CRM_Dataprocessor_Utils_DataSourceFields::getAvailableFieldsInDataSource($joinToSource, $joinToSource->getSourceTitle().' :: ', $joinToSource->getSourceName().'::'));
+    }
+
+    $form->add('select', 'right_field', ts('Select field'), $rightFields, true, array(
+      'style' => 'min-width:250px',
+      'class' => 'crm-select2 huge',
+      'placeholder' => E::ts('- select -'),
+    ));
+
+    // Backwords compatability
+    if (isset($joinConfiguration['right_prefix']) && $joinConfiguration['right_prefix'] == $joinFromSource->getSourceName()) {
+      $joinConfigurationBackwardsCompatibility = $joinConfiguration;
+      $joinConfiguration['left_prefix'] = '';
+      $joinConfiguration['left_field'] = $joinConfigurationBackwardsCompatibility['right_field'];
+      $joinConfiguration['right_prefix'] = $joinConfigurationBackwardsCompatibility['left_prefix'];
+      $joinConfiguration['right_field'] = $joinConfigurationBackwardsCompatibility['left_field'];
+    }
+
+    $defaults = array();
+    if (isset($joinConfiguration['left_prefix'])) {
+      $defaults['left_field'] = $joinConfiguration['left_field'];
+    }
+    if (isset($joinConfiguration['right_prefix'])) {
+      $defaults['right_field'] = $joinConfiguration['right_prefix']."::".$joinConfiguration['right_field'];
+    }
+
+    $form->setDefaults($defaults);
+  }
+
+  /**
+   * When this join has configuration specify the template file name
+   * for the configuration form.
+   *
+   * @return false|string
+   */
+  public function getConfigurationTemplateFileName() {
+    return "CRM/Dataprocessor/Form/MultipleDataFlows/SimpleJoin.tpl";
+  }
+
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @return array
    */
-  public function getConfigurationUrl() {
-    return 'civicrm/dataprocessor/form/joins/simple_join';
+  public function processConfiguration($submittedValues, SourceInterface $joinFromSource) {
+    $left_prefix = $joinFromSource->getSourceName();
+    $left_field = $submittedValues['left_field'];
+    list($right_prefix, $right_field) = explode("::",$submittedValues['right_field'], 2);
+
+    $configuration = array(
+      'left_prefix' => $left_prefix,
+      'left_field' => $left_field,
+      'right_prefix' => $right_prefix,
+      'right_field' => $right_field
+    );
+    return $configuration;
   }
 
   /**
diff --git a/Civi/DataProcessor/DataFlow/MultipleDataFlows/SimpleNonRequiredJoin.php b/Civi/DataProcessor/DataFlow/MultipleDataFlows/SimpleNonRequiredJoin.php
index 4e23a176ff40a1ac549d291f5663eedb25bc7c0d..76f37bcdfc67684e5e173b705c0adfe7753d9521 100644
--- a/Civi/DataProcessor/DataFlow/MultipleDataFlows/SimpleNonRequiredJoin.php
+++ b/Civi/DataProcessor/DataFlow/MultipleDataFlows/SimpleNonRequiredJoin.php
@@ -25,13 +25,6 @@ class SimpleNonRequiredJoin  extends  SimpleJoin {
     parent::__construct($left_prefix, $left_field, $right_prefix, $right_field, $type);
   }
 
-  /**
-   * @return string
-   */
-  public function getConfigurationUrl() {
-    return 'civicrm/dataprocessor/form/joins/simple_join';
-  }
-
   /**
    * @param array $configuration
    *
diff --git a/Civi/DataProcessor/Factory.php b/Civi/DataProcessor/Factory.php
index 245a2bcbc0e6e8e1d711be79b67e239a146f9743..823e2bc52f3ef15799489283b43eedeadaedce33 100644
--- a/Civi/DataProcessor/Factory.php
+++ b/Civi/DataProcessor/Factory.php
@@ -121,9 +121,9 @@ class Factory {
     $this->addOutput('contact_search', 'CRM_DataprocessorSearch_ContactSearch', E::ts('Contact Search'));
     $this->addOutput('activity_search', 'CRM_DataprocessorSearch_ActivitySearch', E::ts('Activity Search'));
     $this->addOutput('export_csv', 'CRM_DataprocessorOutputExport_CSV', E::ts('CSV Export'));
-    $this->addFilter('simple_sql_filter', 'Civi\DataProcessor\FilterHandler\SimpleSqlFilter', E::ts('Simple Filter'));
-    $this->addjoinType('simple_join', 'Civi\DataProcessor\DataFlow\MultipleDataFlows\SimpleJoin', E::ts('Simple Join'));
-    $this->addjoinType('simple_non_required_join', 'Civi\DataProcessor\DataFlow\MultipleDataFlows\SimpleNonRequiredJoin', E::ts('Simple  (but not required) Join'));
+    $this->addFilter('simple_sql_filter', 'Civi\DataProcessor\FilterHandler\SimpleSqlFilter', E::ts('Field filter'));
+    $this->addjoinType('simple_join', 'Civi\DataProcessor\DataFlow\MultipleDataFlows\SimpleJoin', E::ts('Select fields to join on'));
+    $this->addjoinType('simple_non_required_join', 'Civi\DataProcessor\DataFlow\MultipleDataFlows\SimpleNonRequiredJoin', E::ts('Select fields to join on  (but not required) Join'));
   }
 
   /**
diff --git a/Civi/DataProcessor/FilterHandler/AbstractFilterHandler.php b/Civi/DataProcessor/FilterHandler/AbstractFilterHandler.php
index d6420526fc8911441d69a97dc6eb6d08e6265e63..ac98e508f0428a3de9ff56ee8a203d015f6a6752 100644
--- a/Civi/DataProcessor/FilterHandler/AbstractFilterHandler.php
+++ b/Civi/DataProcessor/FilterHandler/AbstractFilterHandler.php
@@ -43,6 +43,38 @@ abstract class AbstractFilterHandler {
    */
   abstract public function setFilter($filterParams);
 
+  /**
+   * File name of the template to add this filter to the criteria form.
+   *
+   * @return string
+   */
+  abstract public function getTemplateFileName();
+
+  /**
+   * Validate the submitted filter parameters.
+   *
+   * @param $submittedValues
+   * @return array
+   */
+  abstract public function validateSubmittedFilterParams($submittedValues);
+
+  /**
+   * Apply the submitted filter
+   *
+   * @param $submittedValues
+   * @throws \Exception
+   */
+  abstract public function applyFilterFromSubmittedFilterParams($submittedValues);
+
+  /**
+   * Add the elements to the filter form.
+   *
+   * @param \CRM_Core_Form $form
+   * @return array
+   *   Return variables belonging to this filter.
+   */
+  abstract public function addToFilterForm(\CRM_Core_Form $form);
+
   public function __construct() {
 
   }
@@ -56,13 +88,49 @@ abstract class AbstractFilterHandler {
   }
 
   /**
-   * Returns the URL to a configuration screen.
-   * Return false when no configuration screen is present.
+   * Returns true when this filter has additional configuration
+   *
+   * @return bool
+   */
+  public function hasConfiguration() {
+    return false;
+  }
+
+  /**
+   * When this filter type has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param array $filter
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $filter=array()) {
+    // Example add a checkbox to the form.
+    // $form->add('checkbox', 'show_label', E::ts('Show label'));
+  }
+
+  /**
+   * When this filter type has configuration specify the template file name
+   * for the configuration form.
    *
    * @return false|string
    */
-  public function getConfigurationUrl() {
+  public function getConfigurationTemplateFileName() {
+    // Example return "CRM/FormFieldLibrary/Form/FieldConfiguration/TextField.tpl";
     return false;
   }
 
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @return array
+   */
+  public function processConfiguration($submittedValues) {
+    // Add the show_label to the configuration array.
+    // $configuration['show_label'] = $submittedValues['show_label'];
+    // return $configuration;
+    return array();
+  }
+
 }
\ No newline at end of file
diff --git a/Civi/DataProcessor/FilterHandler/SimpleSqlFilter.php b/Civi/DataProcessor/FilterHandler/SimpleSqlFilter.php
index ef1c3a3084fc176e49a0329def07ab9726015bb4..5df49c94fef94ffd2e80c8fcdb0f9a042b9bac18 100644
--- a/Civi/DataProcessor/FilterHandler/SimpleSqlFilter.php
+++ b/Civi/DataProcessor/FilterHandler/SimpleSqlFilter.php
@@ -48,9 +48,11 @@ class SimpleSqlFilter extends AbstractFilterHandler {
     $this->is_required = $is_required;
 
     $this->dataSource = $this->data_processor->getDataSourceByName($configuration['datasource']);
-    $this->fieldSpecification  =  clone $this->dataSource->getAvailableFilterFields()->getFieldSpecificationByName($configuration['field']);
-    $this->fieldSpecification->alias = $alias;
-    $this->fieldSpecification->title = $title;
+    if ($this->dataSource) {
+      $this->fieldSpecification  =  clone $this->dataSource->getAvailableFilterFields()->getFieldSpecificationByName($configuration['field']);
+      $this->fieldSpecification->alias = $alias;
+      $this->fieldSpecification->title = $title;
+    }
   }
 
   /**
@@ -78,13 +80,336 @@ class SimpleSqlFilter extends AbstractFilterHandler {
   }
 
   /**
-   * Returns the URL to a configuration screen.
-   * Return false when no configuration screen is present.
+   * Returns true when this filter has additional configuration
+   *
+   * @return bool
+   */
+  public function hasConfiguration() {
+    return true;
+  }
+
+  /**
+   * When this filter type has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param array $filter
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $filter=array()) {
+    $fieldSelect = \CRM_Dataprocessor_Utils_DataSourceFields::getAvailableFieldsInDataSources($filter['data_processor_id']);
+
+    $form->add('select', 'field', E::ts('Field'), $fieldSelect, true, array(
+      'style' => 'min-width:250px',
+      'class' => 'crm-select2 huge',
+      'placeholder' => E::ts('- select -'),
+    ));
+    if (isset($filter['configuration'])) {
+      $configuration = $filter['configuration'];
+      if (isset($configuration['field']) && isset($configuration['datasource'])) {
+        $defaults['field'] = $configuration['datasource'] . '::' . $configuration['field'];
+        $form->setDefaults($defaults);
+      }
+    }
+  }
+
+  /**
+   * When this filter type has configuration specify the template file name
+   * for the configuration form.
    *
    * @return false|string
    */
-  public function getConfigurationUrl() {
-    return 'civicrm/dataprocessor/form/filter/simplefilter';
+  public function getConfigurationTemplateFileName() {
+    return "CRM/Dataprocessor/Form/Filter/Configuration/SimpleSqlFilter.tpl";
+  }
+
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @return array
+   */
+  public function processConfiguration($submittedValues) {
+    list($datasource, $field) = explode('::', $submittedValues['field'], 2);
+    $configuration['field'] = $field;
+    $configuration['datasource'] = $datasource;
+    return $configuration;
+  }
+
+  /**
+   * File name of the template to add this filter to the criteria form.
+   *
+   * @return string
+   */
+  public function getTemplateFileName() {
+    return "CRM/Dataprocessor/Form/Filter/SimpleSqlFilter.tpl";
+  }
+
+  /**
+   * Validate the submitted filter parameters.
+   *
+   * @param $submittedValues
+   * @return array
+   */
+  public function validateSubmittedFilterParams($submittedValues) {
+    $errors = array();
+    if ($this->isRequired()) {
+      $filterSpec = $this->getFieldSpecification();
+      $filterName = $filterSpec->alias;
+      if ($filterSpec->type == 'Date' || $filterSpec->type == 'Timestamp') {
+        $relative = \CRM_Utils_Array::value("{$filterName}_relative", $submittedValues);
+        $from = \CRM_Utils_Array::value("{$filterName}_from", $submittedValues);
+        $to = \CRM_Utils_Array::value("{$filterName}_to", $submittedValues);
+        $fromTime = \CRM_Utils_Array::value("{$filterName}_from_time", $submittedValues);
+        $toTime = \CRM_Utils_Array::value("{$filterName}_to_time", $submittedValues);
+
+        list($from, $to) = \CRM_Utils_Date::getFromTo($relative, $from, $to, $fromTime, $toTime);
+        if (!$from && !$to) {
+          $errors[$filterName . '_relative'] = E::ts('Field %1 is required', [1 => $filterSpec->title]);
+        }
+      }
+      elseif (!isset($submittedValues[$filterName . '_op']) || !(isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value'])) {
+        $errors[$filterName . '_value'] = E::ts('Field %1 is required', [1 => $filterSpec->title]);
+      }
+    }
+    return $errors;
+  }
+
+  /**
+   * Apply the submitted filter
+   *
+   * @param $submittedValues
+   * @throws \Exception
+   */
+  public function applyFilterFromSubmittedFilterParams($submittedValues) {
+    $isFilterSet = FALSE;
+    $filterSpec = $this->getFieldSpecification();
+    $filterName = $filterSpec->alias;
+    if ($filterSpec->type == 'Date' || $filterSpec->type == 'Timestamp') {
+      $isFilterSet = $this->applyDateFilter($submittedValues);
+    }
+    elseif (isset($submittedValues[$filterName . '_op'])) {
+      switch ($submittedValues[$filterName . '_op']) {
+        case 'IN':
+          if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
+            $filterParams = [
+              'op' => 'IN',
+              'value' => $submittedValues[$filterName . '_value'],
+            ];
+            $this->setFilter($filterParams);
+            $isFilterSet = TRUE;
+          }
+          break;
+        case 'NOT IN':
+          if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
+            $filterParams = [
+              'op' => 'NOT IN',
+              'value' => $submittedValues[$filterName . '_value'],
+            ];
+            $this->setFilter($filterParams);
+            $isFilterSet = TRUE;
+          }
+          break;
+        case '=':
+        case '!=':
+        case '>':
+        case '<':
+        case '>=':
+        case '<=':
+          if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
+            $filterParams = [
+              'op' => $submittedValues[$filterName . '_op'],
+              'value' => $submittedValues[$filterName . '_value'],
+            ];
+            $this->setFilter($filterParams);
+            $isFilterSet = TRUE;
+          }
+          break;
+        case 'has':
+          if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
+            $filterParams = [
+              'op' => 'LIKE',
+              'value' => '%' . $submittedValues[$filterName . '_value'] . '%',
+            ];
+            $this->setFilter($filterParams);
+            $isFilterSet = TRUE;
+          }
+          break;
+        case 'nhas':
+          if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
+            $filterParams = [
+              'op' => 'NOT LIKE',
+              'value' => '%' . $submittedValues[$filterName . '_value'] . '%',
+            ];
+            $this->setFilter($filterParams);
+            $isFilterSet = TRUE;
+          }
+          break;
+        case 'sw':
+          if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
+            $filterParams = [
+              'op' => 'LIKE',
+              'value' => $submittedValues[$filterName . '_value'] . '%',
+            ];
+            $this->setFilter($filterParams);
+            $isFilterSet = TRUE;
+          }
+          break;
+        case 'ew':
+          if (isset($submittedValues[$filterName . '_value']) && $submittedValues[$filterName . '_value']) {
+            $filterParams = [
+              'op' => 'LIKE',
+              'value' => '%' . $submittedValues[$filterName . '_value'],
+            ];
+            $this->setFilter($filterParams);
+            $isFilterSet = TRUE;
+          }
+          break;
+      }
+    }
+    if ($this->isRequired() && !$isFilterSet) {
+      throw new \Exception('Field ' . $filterSpec->title . ' is required');
+    }
   }
 
+  /**
+   * Add the elements to the filter form.
+   *
+   * @param \CRM_Core_Form $form
+   * @return array
+   *   Return variables belonging to this filter.
+   */
+  public function addToFilterForm(\CRM_Core_Form $form) {
+    static $count = 1;
+    $types = \CRM_Utils_Type::getValidTypes();
+    $fieldSpec = $this->getFieldSpecification();
+    $operations = $this->getOperatorOptions($fieldSpec);
+    $type = \CRM_Utils_Type::T_STRING;
+
+    $title = $fieldSpec->title;
+    if ($this->isRequired()) {
+      $title .= ' <span class="crm-marker">*</span>';
+    }
+
+    if (isset($types[$fieldSpec->type])) {
+      $type = $types[$fieldSpec->type];
+    }
+    if ($fieldSpec->getOptions()) {
+      $form->addElement('select', "{$fieldSpec->alias}_op", E::ts('Operator:'), $operations);
+      $form->addElement('select', "{$fieldSpec->alias}_value", NULL, $fieldSpec->getOptions(), [
+        'style' => 'min-width:250px',
+        'class' => 'crm-select2 huge',
+        'multiple' => TRUE,
+        'placeholder' => E::ts('- select -'),
+      ]);
+    }
+    else {
+      switch ($type) {
+        case \CRM_Utils_Type::T_DATE:
+        case \CRM_Utils_Type::T_TIMESTAMP:
+          \CRM_Core_Form_Date::buildDateRange($form, $fieldSpec->alias, $count, '_from', '_to', E::ts('From:'), $this->isRequired(), $operations);
+          $count ++;
+          break;
+        case \CRM_Utils_Type::T_INT:
+        case \CRM_Utils_Type::T_FLOAT:
+          // and a min value input box
+          $form->add('text', "{$fieldSpec->alias}_min", E::ts('Min'));
+          // and a max value input box
+          $form->add('text', "{$fieldSpec->alias}_max", E::ts('Max'));
+        default:
+          // default type is string
+          $form->addElement('select', "{$fieldSpec->alias}_op", E::ts('Operator:'), $operations,
+            ['onchange' => "return showHideMaxMinVal( '$fieldSpec->alias', this.value );"]
+          );
+          // we need text box for value input
+          $form->add('text', "{$fieldSpec->alias}_value", NULL, ['class' => 'huge']);
+          break;
+      }
+    }
+
+    $filter['type'] = $fieldSpec->type;
+    $filter['title'] = $title;
+
+    return $filter;
+  }
+
+  protected function getOperatorOptions(\Civi\DataProcessor\DataSpecification\FieldSpecification $fieldSpec) {
+    if ($fieldSpec->getOptions()) {
+      return array(
+        'IN' => E::ts('Is one of'),
+        'NOT IN' => E::ts('Is not one of'),
+      );
+    }
+    $types = \CRM_Utils_Type::getValidTypes();
+    $type = \CRM_Utils_Type::T_STRING;
+    if (isset($types[$fieldSpec->type])) {
+      $type = $types[$fieldSpec->type];
+    }
+    switch ($type) {
+      case \CRM_Utils_Type::T_DATE:
+        return array();
+        break;
+      case \CRM_Utils_Type::T_INT:
+      case \CRM_Utils_Type::T_FLOAT:
+        return array(
+          '=' => E::ts('Is equal to'),
+          '<=' => E::ts('Is less than or equal to'),
+          '>=' => E::ts('Is greater than or equal to'),
+          '<' => E::ts('Is less than'),
+          '>' => E::ts('Is greater than'),
+          '!=' => E::ts('Is not equal to'),
+        );
+        break;
+    }
+    return array(
+      '=' => E::ts('Is equal to'),
+      '!=' => E::ts('Is not equal to'),
+      'has' => E::ts('Contains'),
+      'sw' => E::ts('Starts with'),
+      'ew' => E::ts('Ends with'),
+      'nhas' => E::ts('Does not contain'),
+    );
+  }
+
+  /**
+   * @param array $submittedValues
+   * @return string|null
+   */
+  protected function applyDateFilter($submittedValues) {
+    $filterName = $this->getFieldSpecification()->alias;
+    $type = $this->getFieldSpecification()->type;
+    $relative = \CRM_Utils_Array::value("{$filterName}_relative", $submittedValues);
+    $from = \CRM_Utils_Array::value("{$filterName}_from", $submittedValues);
+    $to = \CRM_Utils_Array::value("{$filterName}_to", $submittedValues);
+    $fromTime = \CRM_Utils_Array::value("{$filterName}_from_time", $submittedValues);
+    $toTime = \CRM_Utils_Array::value("{$filterName}_to_time", $submittedValues);
+
+    list($from, $to) = \CRM_Utils_Date::getFromTo($relative, $from, $to, $fromTime, $toTime);
+    if ($from && $to) {
+      $from = ($type == "Date") ? substr($from, 0, 8) : $from;
+      $to = ($type == "Date") ? substr($to, 0, 8) : $to;
+      $this->setFilter(array(
+        'op' => 'BETWEEN',
+        'value' => array($from, $to),
+      ));
+      return TRUE;
+    } elseif ($from) {
+      $from = ($type == "Date") ? substr($from, 0, 8) : $from;
+      $this->setFilter(array(
+        'op' => '>=',
+        'value' => $from,
+      ));
+      return TRUE;
+    } elseif ($to) {
+      $to = ($type == "Date") ? substr($to, 0, 8) : $to;
+      $this->setFilter(array(
+        'op' => '<=',
+        'value' => $to,
+      ));
+      return TRUE;
+    }
+    return FALSE;
+  }
+
+
 }
\ No newline at end of file
diff --git a/Civi/DataProcessor/Output/Api.php b/Civi/DataProcessor/Output/Api.php
index 44a13c3d148995c68d19c6de80d3b9f741869900..55c3f3d16175ade2b99db1ffaf13aa82eb5e53f1 100644
--- a/Civi/DataProcessor/Output/Api.php
+++ b/Civi/DataProcessor/Output/Api.php
@@ -13,6 +13,8 @@ use Civi\API\Provider\ProviderInterface as API_ProviderInterface;
 use Civi\DataProcessor\ProcessorType\AbstractProcessorType;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
+use \CRM_Dataprocessor_ExtensionUtil as E;
+
 class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInterface{
 
   public function __construct() {
@@ -20,13 +22,66 @@ class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInte
   }
 
   /**
-   * Return the url to a configuration page.
-   * Or return false when no configuration page exists.
+   * Returns true when this filter has additional configuration
+   *
+   * @return bool
+   */
+  public function hasConfiguration() {
+    return true;
+  }
+
+  /**
+   * When this filter type has additional configuration you can add
+   * the fields on the form with this function.
    *
-   * @return string|false
+   * @param \CRM_Core_Form $form
+   * @param array $filter
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $output=array()) {
+    $form->add('select','permission', E::ts('Permission'), \CRM_Core_Permission::basicPermissions(), true, array(
+      'style' => 'min-width:250px',
+      'class' => 'crm-select2 huge',
+      'placeholder' => E::ts('- select -'),
+    ));
+    $form->add('text', 'api_entity', E::ts('API Entity'), true);
+    $form->add('text', 'api_action', E::ts('API Action Name'), true);
+    $form->add('text', 'api_count_action', E::ts('API GetCount Action Name'), true);
+
+    if ($output) {
+      $defaults['permission'] = $output['permission'];
+      $defaults['api_entity'] = $output['api_entity'];
+      $defaults['api_action'] = $output['api_action'];
+      $defaults['api_count_action'] = $output['api_count_action'];
+    } else {
+      $defaults['permission'] = 'access CiviCRM';
+    }
+    $form->setDefaults($defaults);
+  }
+
+  /**
+   * When this filter type has configuration specify the template file name
+   * for the configuration form.
+   *
+   * @return false|string
+   */
+  public function getConfigurationTemplateFileName() {
+    return "CRM/Dataprocessor/Form/Output/API.tpl";
+  }
+
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @param array $output
+   * @return array
    */
-  public function getConfigurationUrl() {
-    return 'civicrm/dataprocessor/form/output/api';
+  public function processConfiguration($submittedValues, &$output) {
+    $output['permission'] = $submittedValues['permission'];
+    $output['api_entity'] = $submittedValues['api_entity'];
+    $output['api_action'] = $submittedValues['api_action'];
+    $output['api_count_action'] = $submittedValues['api_count_action'];
+    return array();
   }
 
   /**
@@ -93,10 +148,11 @@ class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInte
         if (!$dao->fetch()) {
           throw new \API_Exception("Could not find a data processor");
         }
-        $dataProcessor = \CRM_Dataprocessor_BAO_DataProcessor::getDataProcessorById($dao->data_processor_id);
+        $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $dao->data_processor_id));
+        $dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($dataProcessor);
 
 
-        foreach ($dataProcessor->getDataFlow()->getOutputFieldHandlers() as $outputFieldHandler) {
+        foreach ($dataProcessorClass->getDataFlow()->getOutputFieldHandlers() as $outputFieldHandler) {
           $fieldSpec = $outputFieldHandler->getOutputFieldSpecification();
           $type = \CRM_Utils_Type::T_STRING;
           if (isset($types[$fieldSpec->type])) {
@@ -117,7 +173,7 @@ class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInte
           }
           $result['values'][$fieldSpec->alias] = $field;
         }
-        foreach($dataProcessor->getFilterHandlers() as $filterHandler) {
+        foreach($dataProcessorClass->getFilterHandlers() as $filterHandler) {
           $fieldSpec = $filterHandler->getFieldSpecification();
           $type = \CRM_Utils_Type::T_STRING;
           if (isset($types[$fieldSpec->type])) {
@@ -182,10 +238,11 @@ class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInte
     if (strtolower($dao->api_count_action) == $apiRequest['action']) {
       $isCountAction = TRUE;
     }
-    $dataProcessor = \CRM_Dataprocessor_BAO_DataProcessor::getDataProcessorById($dao->data_processor_id);
+    $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $dao->data_processor_id));
+    $dataProcessorClass = \CRM_Dataprocessor_BAO_DataProcessor::dataProcessorToClass($dataProcessor);
 
     $params = $apiRequest['params'];
-    foreach($dataProcessor->getFilterHandlers() as $filter) {
+    foreach($dataProcessorClass->getFilterHandlers() as $filter) {
       $filterSpec = $filter->getFieldSpecification();
       if ($filter->isRequired() && !isset($params[$filterSpec->alias])) {
         throw new \API_Exception('Field '.$filterSpec->alias.' is required');
@@ -208,27 +265,27 @@ class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInte
     }
 
     if ($isCountAction) {
-      $count = $dataProcessor->getDataFlow()->recordCount();
+      $count = $dataProcessorClass->getDataFlow()->recordCount();
       return array('result' => $count, 'is_error' => 0);
     } else {
       $options = _civicrm_api3_get_options_from_params($apiRequest['params']);
 
       if (isset($options['limit']) && $options['limit'] > 0) {
-        $dataProcessor->getDataFlow()->setLimit($options['limit']);
+        $dataProcessorClass->getDataFlow()->setLimit($options['limit']);
       }
       if (isset($options['offset'])) {
-        $dataProcessor->getDataFlow()->setOffset($options['offset']);
+        $dataProcessorClass->getDataFlow()->setOffset($options['offset']);
       }
       if (isset($options['sort'])) {
         $sort = explode(', ', $options['sort']);
         foreach ($sort as $index => &$sortString) {
           // Get sort field and direction
           list($sortField, $dir) = array_pad(explode(' ', $sortString), 2, 'ASC');
-          $dataProcessor->getDataFlow()->addSort($sortField, $dir);
+          $dataProcessorClass->getDataFlow()->addSort($sortField, $dir);
         }
       }
 
-      $records = $dataProcessor->getDataFlow()->allRecords();
+      $records = $dataProcessorClass->getDataFlow()->allRecords();
       $values = array();
       foreach($records as $idx => $record) {
         foreach($record as $fieldname => $field) {
@@ -241,7 +298,7 @@ class Api implements OutputInterface, API_ProviderInterface, EventSubscriberInte
         'is_error' => 0,
       );
       if (isset($apiRequest['params']['debug']) && $apiRequest['params']['debug']) {
-        $return['debug_info'] = $dataProcessor->getDataFlow()->getDebugInformation();
+        $return['debug_info'] = $dataProcessorClass->getDataFlow()->getDebugInformation();
       }
       return $return;
     }
diff --git a/Civi/DataProcessor/Output/ExportOutputInterface.php b/Civi/DataProcessor/Output/ExportOutputInterface.php
index 1c10004558b18c09e3e2458a7d4dd2c16682d442..7c925472980a724a8901c40fa8c7d85300da89ff 100644
--- a/Civi/DataProcessor/Output/ExportOutputInterface.php
+++ b/Civi/DataProcessor/Output/ExportOutputInterface.php
@@ -18,15 +18,15 @@ interface ExportOutputInterface extends OutputInterface {
   /**
    * Download export
    *
-   * @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor
-   * @param array $dataProcessorBAO
+   * @param \Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessorClass
+   * @param array $dataProcessor
    * @param array $outputBAO
    * @param array $formValues
    * @param string $sortFieldName
    * @param string $sortDirection
    * @return string
    */
-  public function downloadExport(\Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessor, $dataProcessorBAO, $outputBAO, $formValues, $sortFieldName = null, $sortDirection = 'ASC');
+  public function downloadExport(\Civi\DataProcessor\ProcessorType\AbstractProcessorType $dataProcessorClass, $dataProcessor, $outputBAO, $formValues);
 
   /**
    * Returns the mime type of the export file.
diff --git a/Civi/DataProcessor/Output/OutputInterface.php b/Civi/DataProcessor/Output/OutputInterface.php
index e3a780e7bc3d35cc4cbcbf476745bdac964df8cb..89e871be0377cb10c961c9e1d261d18e8abf54e1 100644
--- a/Civi/DataProcessor/Output/OutputInterface.php
+++ b/Civi/DataProcessor/Output/OutputInterface.php
@@ -9,11 +9,37 @@ namespace Civi\DataProcessor\Output;
 interface OutputInterface {
 
   /**
-   * Return the url to a configuration page.
-   * Or return false when no configuration page exists.
+   * Returns true when this output has additional configuration
    *
-   * @return string|false
+   * @return bool
    */
-  public function getConfigurationUrl();
+  public function hasConfiguration();
+
+  /**
+   * When this output type has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param array $output
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $output=array());
+
+  /**
+   * When this output type has configuration specify the template file name
+   * for the configuration form.
+   *
+   * @return false|string
+   */
+  public function getConfigurationTemplateFileName();
+
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @param array $output
+   * @return array $output
+   */
+  public function processConfiguration($submittedValues, &$output);
 
 }
\ No newline at end of file
diff --git a/Civi/DataProcessor/Output/UIOutputHelper.php b/Civi/DataProcessor/Output/UIOutputHelper.php
index f3fc61dbce8373e5abb109ba8a3466a9d8698b47..68576dad59e40c53b4897e9d872ebd984e79c8d4 100644
--- a/Civi/DataProcessor/Output/UIOutputHelper.php
+++ b/Civi/DataProcessor/Output/UIOutputHelper.php
@@ -34,10 +34,8 @@ class UIOutputHelper {
     while ($dao->fetch()) {
       $outputClass = $factory->getOutputByName($dao->type);
       if ($outputClass instanceof \Civi\DataProcessor\Output\UIOutputInterface) {
-        $outputs = \CRM_Dataprocessor_BAO_Output::getValues(['id' => $dao->output_id]);
-        $output = $outputs[$dao->output_id];
-        $dataprocessors = \CRM_Dataprocessor_BAO_DataProcessor::getValues(['id' => $dao->id]);
-        $dataprocessor = $dataprocessors[$dao->id];
+        $output = civicrm_api3('DataProcessorOutput', 'getsingle', array('id' => $dao->output_id));
+        $dataprocessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $dao->id));
         $url = $outputClass->getUrlToUi($output, $dataprocessor);
 
         $configuration = json_decode($dao->configuration, TRUE);
@@ -68,34 +66,32 @@ class UIOutputHelper {
       return;
     }
     if ($op == 'delete') {
-      $outputs = \CRM_Dataprocessor_BAO_Output::getValues(array('id' => $id));
-      if (isset($outputs[$id]['configuration']['navigation_id'])) {
-        $navId = $outputs[$id]['configuration']['navigation_id'];
+      $output = civicrm_api3('DataProcessorOutput', 'getsingle', array('id' => $id));
+      if (isset($output['configuration']['navigation_id'])) {
+        $navId = $output['configuration']['navigation_id'];
         \CRM_Core_BAO_Navigation::processDelete($navId);
         \CRM_Core_BAO_Navigation::resetNavigation();
         self::$rebuildMenu = TRUE;
       }
     } elseif ($op == 'edit') {
-      $outputs = \CRM_Dataprocessor_BAO_Output::getValues(array('id' => $id));
-      $output = $outputs[$id];
+      $output = civicrm_api3('DataProcessorOutput', 'getsingle', array('id' => $id));
       if (!isset($output['configuration']['navigation_id']) && !isset($params['configuration']['navigation_parent_path'])) {
         return;
       } elseif (!isset($params['configuration']['navigation_parent_path'])) {
         // Delete the navigation item
-        $navId = $outputs[$id]['configuration']['navigation_id'];
+        $navId = $output['configuration']['navigation_id'];
         \CRM_Core_BAO_Navigation::processDelete($navId);
         \CRM_Core_BAO_Navigation::resetNavigation();
         self::$rebuildMenu = TRUE;
       } else {
-        $dataProcessors = \CRM_Dataprocessor_BAO_DataProcessor::getValues(['id' => $output['data_processor_id']]);
-        $dataProcessor = $dataProcessors[$output['data_processor_id']];
+        $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $output['data_processor_id']));
 
         // Retrieve the current navigation params.
         $navigationParams = [];
-        if (isset($outputs[$id]['configuration']['navigation_id'])) {
+        if (isset($output['configuration']['navigation_id'])) {
           // Get the default navigation parent id.
           $navigationDefaults = [];
-          $navParams = ['id' => $outputs[$id]['configuration']['navigation_id']];
+          $navParams = ['id' => $output['configuration']['navigation_id']];
           \CRM_Core_BAO_Navigation::retrieve($navParams, $navigationDefaults);
           if (!empty($navigationDefaults['id'])) {
             $navigationParams['id'] = $navigationDefaults['id'];
@@ -107,8 +103,7 @@ class UIOutputHelper {
       }
     }
     elseif ($op == 'create' && isset($params['configuration']['navigation_parent_path'])) {
-      $dataProcessors = \CRM_Dataprocessor_BAO_DataProcessor::getValues(array('id' => $params['data_processor_id']));
-      $dataProcessor = $dataProcessors[$params['data_processor_id']];
+      $dataProcessor = civicrm_api3('DataProcessor', 'getsingle', array('id' => $params['data_processor_id']));
       self::$rebuildMenu = self::newNavigationItem($params, $dataProcessor);
     }
   }
diff --git a/Civi/DataProcessor/Source/AbstractCivicrmEntitySource.php b/Civi/DataProcessor/Source/AbstractCivicrmEntitySource.php
index 434ac16baaefe67f4b5e9e60834e8ef759e9998f..ad21e062a142d0474976b38cab52174cbf85a36c 100644
--- a/Civi/DataProcessor/Source/AbstractCivicrmEntitySource.php
+++ b/Civi/DataProcessor/Source/AbstractCivicrmEntitySource.php
@@ -354,15 +354,6 @@ abstract class AbstractCivicrmEntitySource extends AbstractSource {
     }
   }
 
-  /**
-   * Returns URL to configuration screen
-   *
-   * @return false|string
-   */
-  public function getConfigurationUrl() {
-    return 'civicrm/dataprocessor/form/source/configuration';
-  }
-
   /**
    * @return \Civi\DataProcessor\DataFlow\SqlDataFlow
    */
diff --git a/Civi/DataProcessor/Source/AbstractSource.php b/Civi/DataProcessor/Source/AbstractSource.php
index 7511c74aad2123c52642a37169e4d0dc849e0bf6..eb63b1a2e7643992566367010360331470911d1e 100644
--- a/Civi/DataProcessor/Source/AbstractSource.php
+++ b/Civi/DataProcessor/Source/AbstractSource.php
@@ -6,11 +6,12 @@
 
 namespace Civi\DataProcessor\Source;
 
-
 use Civi\DataProcessor\DataFlow\MultipleDataFlows\JoinInterface;
 use Civi\DataProcessor\DataSpecification\FieldSpecification;
 use Civi\DataProcessor\ProcessorType\AbstractProcessorType;
 
+use CRM_Dataprocessor_ExtensionUtil as E;
+
 abstract class AbstractSource implements SourceInterface {
 
   /**
@@ -181,4 +182,143 @@ abstract class AbstractSource implements SourceInterface {
     return array();
   }
 
+  /**
+   * Returns true when this source has additional configuration
+   *
+   * @return bool
+   */
+  public function hasConfiguration() {
+    return count($this->getAvailableFilterFields()->getFields()) > 0 ? true : false;
+  }
+
+  /**
+   * Returns an array with the names of required configuration filters.
+   * Those filters are displayed as required to the user
+   *
+   * @return array
+   */
+  protected function requiredConfigurationFilters() {
+    return array();
+  }
+
+  /**
+   * When this source has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param array $source
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $source=array()) {
+    $fields = array();
+    $required_fields = array();
+    $requiredFilters = $this->requiredConfigurationFilters();
+    foreach($this->getAvailableFilterFields()->getFields() as $fieldSpec) {
+      $alias = $fieldSpec->name;
+      $isRequired = false;
+      if (in_array($alias, $requiredFilters)) {
+        $isRequired = true;
+      }
+      switch ($fieldSpec->type) {
+        case 'Boolean':
+          if ($isRequired) {
+            $required_fields[$alias] = $fieldSpec->title;
+          } else {
+            $fields[$alias] = $fieldSpec->title;
+          }
+          $form->addElement('select', "{$alias}_op", ts('Operator:'), [
+            '=' => E::ts('Is equal to'),
+            '!=' => E::ts('Is not equal to'),
+          ]);
+          if (!empty($fieldSpec->getOptions())) {
+            $form->addElement('select', "{$alias}_value", $fieldSpec->title, array('' => E::ts(' - Select - ')) + $fieldSpec->getOptions());
+          }
+          break;
+        default:
+          if ($fieldSpec->getOptions()) {
+            if ($isRequired) {
+              $required_fields[$alias] = $fieldSpec->title;
+            } else {
+              $fields[$alias] = $fieldSpec->title;
+            }
+            $form->addElement('select', "{$alias}_op", ts('Operator:'), [
+              'IN' => E::ts('Is one of'),
+              'NOT IN' => E::ts('Is not one of'),
+            ]);
+            $form->addElement('select', "{$alias}_value", $fieldSpec->title, $fieldSpec->getOptions(), array(
+              'style' => 'min-width:250px',
+              'class' => 'crm-select2 huge',
+              'multiple' => 'multiple',
+              'placeholder' => E::ts('- select -'),
+            ));
+          }
+      }
+    }
+    $form->assign('filter_fields', $fields);
+    $form->assign('filter_required_fields', $required_fields);
+
+    $defaults = array();
+    if (isset($source['configuration']['filter'])) {
+      foreach($source['configuration']['filter'] as $alias => $filter) {
+        $defaults[$alias.'_op'] = $filter['op'];
+        $defaults[$alias.'_value'] = $filter['value'];
+      }
+    }
+    $form->setDefaults($defaults);
+  }
+
+  /**
+   * When this source has configuration specify the template file name
+   * for the configuration form.
+   *
+   * @return false|string
+   */
+  public function getConfigurationTemplateFileName() {
+    return "CRM/Dataprocessor/Form/Source/Configuration.tpl";
+  }
+
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @return array
+   */
+  public function processConfiguration($submittedValues) {
+    $configuration = array();
+    $filter_config = array();
+    foreach($this->getAvailableFilterFields()->getFields() as $fieldSpec) {
+      $alias = $fieldSpec->name;
+      if ($this->valueSubmittedAndNotEmpty($alias.'_value', $submittedValues)) {
+        $filter_config[$alias] = array(
+          'op' => $submittedValues[$alias.'_op'],
+          'value' => $submittedValues[$alias.'_value']
+        );
+      }
+    }
+    $configuration['filter'] = $filter_config;
+
+    return $configuration;
+  }
+
+  /**
+   * Checks whether a value is submitted and not empty.
+   *
+   * @param $field
+   * @param $values
+   *
+   * @return bool
+   */
+  protected function valueSubmittedAndNotEmpty($field, $values) {
+    if (!isset($values[$field])) {
+      return false;
+    }
+    if (is_array($values[$field]) && count($values[$field]) === 0) {
+      return false;
+    }
+    if (is_string($values[$field]) && strlen($values[$field]) === 0) {
+      return false;
+    }
+    return true;
+  }
+
 }
\ No newline at end of file
diff --git a/Civi/DataProcessor/Source/CSV.php b/Civi/DataProcessor/Source/CSV.php
index 696e68b040deb604768c9c03579bb13af7221b95..0a45f052f0cf7f9a58cb9655fd7b081ae06759f5 100644
--- a/Civi/DataProcessor/Source/CSV.php
+++ b/Civi/DataProcessor/Source/CSV.php
@@ -12,6 +12,8 @@ use Civi\DataProcessor\DataFlow\InMemoryDataFlow;
 use Civi\DataProcessor\DataSpecification\DataSpecification;
 use Civi\DataProcessor\DataSpecification\FieldSpecification;
 
+use CRM_Dataprocessor_ExtensionUtil as E;
+
 class CSV extends AbstractSource {
 
   protected $headerRow;
@@ -64,12 +66,70 @@ class CSV extends AbstractSource {
   }
 
   /**
-   * Returns URL to configuration screen
+   * Returns true when this source has additional configuration
+   *
+   * @return bool
+   */
+  public function hasConfiguration() {
+    return true;
+  }
+
+  /**
+   * When this source has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param array $source
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $source=array()) {
+    $form->add('text', 'uri', E::ts('URI'), true);
+    $form->add('text', 'delimiter', E::ts('Field delimiter'), true);
+    $form->add('text', 'enclosure', E::ts('Field enclosure character'), true);
+    $form->add('text', 'escape', E::ts('Escape character'), true);
+    $form->add('checkbox', 'first_row_as_header', E::ts('First row contains column names'));
+
+    $defaults = array();
+    foreach($source['configuration'] as $field => $value) {
+      $defaults[$field] = $value;
+    }
+    if (!isset($defaults['delimiter'])) {
+      $defaults['delimiter'] = ',';
+    }
+    if (!isset($defaults['enclosure'])) {
+      $defaults['enclosure'] = '"';
+    }
+    if (!isset($defaults['escape'])) {
+      $defaults['escape'] = '\\';
+    }
+    $form->setDefaults($defaults);
+  }
+
+  /**
+   * When this source has configuration specify the template file name
+   * for the configuration form.
    *
    * @return false|string
    */
-  public function getConfigurationUrl() {
-    return 'civicrm/dataprocessor/form/source/csv';
+  public function getConfigurationTemplateFileName() {
+    return "CRM/Dataprocessor/Form/Source/Csv.tpl";
+  }
+
+
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @return array
+   */
+  public function processConfiguration($submittedValues) {
+    $configuration = array();
+    $configuration['uri'] = $submittedValues['uri'];
+    $configuration['delimiter'] = $submittedValues['delimiter'];
+    $configuration['enclosure'] = $submittedValues['enclosure'];
+    $configuration['escape'] = $submittedValues['escape'];
+    $configuration['first_row_as_header'] = $submittedValues['first_row_as_header'];
+
+    return $configuration;
   }
 
 }
\ No newline at end of file
diff --git a/Civi/DataProcessor/Source/Contact/AddressSource.php b/Civi/DataProcessor/Source/Contact/AddressSource.php
index 0569b810ed065d0c76119920b95a2c786a3e9496..ad742167ee2aa2faba4e683dfdbc11a93b108cb7 100644
--- a/Civi/DataProcessor/Source/Contact/AddressSource.php
+++ b/Civi/DataProcessor/Source/Contact/AddressSource.php
@@ -30,4 +30,32 @@ class AddressSource extends AbstractCivicrmEntitySource {
     return 'civicrm_address';
   }
 
+  /**
+   * Returns an array with the names of required configuration filters.
+   * Those filters are displayed as required to the user
+   *
+   * @return array
+   */
+  protected function requiredConfigurationFilters() {
+    return array(
+      'is_primary',
+    );
+  }
+
+  /**
+   * Returns the default configuration for this data source
+   *
+   * @return array
+   */
+  public function getDefaultConfiguration() {
+    return array(
+      'filter' => array(
+        'is_primary' => array (
+          'op' => '=',
+          'value' => '1',
+        ),
+      )
+    );
+  }
+
 }
\ No newline at end of file
diff --git a/Civi/DataProcessor/Source/Contact/EmailSource.php b/Civi/DataProcessor/Source/Contact/EmailSource.php
index 15c4526b58d8d9663c5d295a9f0fa39050f3ab32..5239f9b9cf2b310b5979034ff16b92c3b4acea94 100644
--- a/Civi/DataProcessor/Source/Contact/EmailSource.php
+++ b/Civi/DataProcessor/Source/Contact/EmailSource.php
@@ -30,4 +30,32 @@ class EmailSource extends AbstractCivicrmEntitySource {
     return 'civicrm_email';
   }
 
+  /**
+   * Returns an array with the names of required configuration filters.
+   * Those filters are displayed as required to the user
+   *
+   * @return array
+   */
+  protected function requiredConfigurationFilters() {
+    return array(
+      'is_primary',
+    );
+  }
+
+  /**
+   * Returns the default configuration for this data source
+   *
+   * @return array
+   */
+  public function getDefaultConfiguration() {
+    return array(
+      'filter' => array(
+        'is_primary' => array (
+          'op' => '=',
+          'value' => '1',
+        ),
+      )
+    );
+  }
+
 }
\ No newline at end of file
diff --git a/Civi/DataProcessor/Source/Contact/PhoneSource.php b/Civi/DataProcessor/Source/Contact/PhoneSource.php
index 0eadb7feba688a2002497548a8e94ea6aa13e890..5af1d4715025d8aaeb9121e6698756031a9250c6 100644
--- a/Civi/DataProcessor/Source/Contact/PhoneSource.php
+++ b/Civi/DataProcessor/Source/Contact/PhoneSource.php
@@ -30,4 +30,32 @@ class PhoneSource extends AbstractCivicrmEntitySource {
     return 'civicrm_phone';
   }
 
+  /**
+   * Returns an array with the names of required configuration filters.
+   * Those filters are displayed as required to the user
+   *
+   * @return array
+   */
+  protected function requiredConfigurationFilters() {
+    return array(
+      'is_primary',
+    );
+  }
+
+  /**
+   * Returns the default configuration for this data source
+   *
+   * @return array
+   */
+  public function getDefaultConfiguration() {
+    return array(
+      'filter' => array(
+        'is_primary' => array (
+          'op' => '=',
+          'value' => '1',
+        ),
+      )
+    );
+  }
+
 }
\ No newline at end of file
diff --git a/Civi/DataProcessor/Source/Contact/RelationshipSource.php b/Civi/DataProcessor/Source/Contact/RelationshipSource.php
index 4e79cf58cf9ae158cca381392dfef19ade357acf..6990a8e792b1fc78b2977482e9bad987c3e79c5f 100644
--- a/Civi/DataProcessor/Source/Contact/RelationshipSource.php
+++ b/Civi/DataProcessor/Source/Contact/RelationshipSource.php
@@ -57,6 +57,19 @@ class RelationshipSource extends AbstractCivicrmEntitySource {
     return $this->availableFilterFields;
   }
 
+  /**
+   * Returns an array with the names of required configuration filters.
+   * Those filters are displayed as required to the user
+   *
+   * @return array
+   */
+  protected function requiredConfigurationFilters() {
+    return array(
+      'relationship_type_id',
+      'is_active',
+    );
+  }
+
   /**
    * Adds an inidvidual filter to the data source
    *
diff --git a/Civi/DataProcessor/Source/SourceInterface.php b/Civi/DataProcessor/Source/SourceInterface.php
index d4a28eb810e8b4d8dd917c5b12291e60864bebf7..22ce991c60889b6309eeb448642a2235692374b4 100644
--- a/Civi/DataProcessor/Source/SourceInterface.php
+++ b/Civi/DataProcessor/Source/SourceInterface.php
@@ -73,13 +73,6 @@ interface SourceInterface {
    */
   public function getAvailableAggregationFields();
 
-  /**
-   * Returns URL to configuration screen
-   *
-   * @return false|string
-   */
-  public function getConfigurationUrl();
-
   /**
    * Ensure that filter field is accesible in the query
    *
@@ -129,4 +122,35 @@ interface SourceInterface {
    */
   public function setSourceTitle($title);
 
+  /**
+   * Returns true when this source has additional configuration
+   *
+   * @return bool
+   */
+  public function hasConfiguration();
+
+  /**
+   * When this source has additional configuration you can add
+   * the fields on the form with this function.
+   *
+   * @param \CRM_Core_Form $form
+   * @param array $source
+   */
+  public function buildConfigurationForm(\CRM_Core_Form $form, $source=array());
+
+  /**
+   * When this source has configuration specify the template file name
+   * for the configuration form.
+   *
+   * @return false|string
+   */
+  public function getConfigurationTemplateFileName();
+  /**
+   * Process the submitted values and create a configuration array
+   *
+   * @param $submittedValues
+   * @return array
+   */
+  public function processConfiguration($submittedValues);
+
 }
\ No newline at end of file
diff --git a/api/v3/DataProcessor.php b/api/v3/DataProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e865ff263924ae472087d662567616b3204a21f
--- /dev/null
+++ b/api/v3/DataProcessor.php
@@ -0,0 +1,142 @@
+<?php
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+/**
+ * DataProcessor.create API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function _civicrm_api3_data_processor_create_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessor::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+  }
+}
+
+/**
+ * DataProcessor.create API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_create($params) {
+  $id = null;
+  if (isset($params['id'])) {
+    $id = $params['id'];
+  }
+  if (isset($params['title'])) {
+    $params['name'] = CRM_Dataprocessor_BAO_DataProcessor::checkName($params['title'], $id, $params['name']);
+  }
+  if (!isset($params['id']) && !isset($params['type'])) {
+    $params['type'] = 'default';
+  }
+  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessor.delete API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function civicrm_api3_data_processor_delete_spec(&$spec) {
+  $spec['id']['api.required'] = true;
+}
+
+/**
+ * DataProcessor.delete API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_delete($params) {
+  CRM_Dataprocessor_BAO_DataProcessorOutput::deleteWithDataProcessorId($params['id']);
+  CRM_Dataprocessor_BAO_DataProcessorField::deleteWithDataProcessorId($params['id']);
+  CRM_Dataprocessor_BAO_DataProcessorFilter::deleteWithDataProcessorId($params['id']);
+  CRM_Dataprocessor_BAO_DataProcessorSource::deleteWithDataProcessorId($params['id']);
+  return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessor.get API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function civicrm_api3_data_processor_get_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessor::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+  }
+}
+
+/**
+ * DataProcessor.get API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_get($params) {
+  $return = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  foreach($return['values'] as $id => $value) {
+    if (isset($value['configuration'])) {
+      $return['values'][$id]['configuration'] = json_decode($value['configuration'], TRUE);
+    } else {
+      $return['values'][$id]['configuration'] = array();
+    }
+    if (isset($value['aggregation'])) {
+      $return['values'][$id]['aggregation'] = json_decode($value['aggregation'], TRUE);
+    } else {
+      $return['values'][$id]['aggregation'] = array();
+    }
+    if (isset($value['storage_configuration'])) {
+      $return['values'][$id]['storage_configuration'] = json_decode($value['storage_configuration'], TRUE);
+    } else {
+      $return['values'][$id]['storage_configuration'] = array();
+    }
+  }
+  return $return;
+}
+
+/**
+ * DataProcessor.check_name API specification
+ *
+ * @param $params
+ */
+function _civicrm_api3_data_processor_check_name_spec($params) {
+  $params['id'] = array(
+    'name' => 'id',
+    'title' => E::ts('ID'),
+  );
+  $params['title'] = array(
+    'name' => 'title',
+    'title' => E::ts('Title'),
+    'api.required' => true,
+  );
+  $params['name'] = array(
+    'name' => 'name',
+    'title' => E::ts('Name'),
+  );
+}
+
+/**
+ * DataProcessor.check_name API
+ *
+ * @param $params
+ */
+function civicrm_api3_data_processor_check_name($params) {
+  $name = CRM_Dataprocessor_BAO_DataProcessor::checkName($params['title'], $params['id'], $params['name']);
+  return array(
+    'name' => $name,
+  );
+}
diff --git a/api/v3/DataProcessor/Create.php b/api/v3/DataProcessor/Create.php
deleted file mode 100644
index 268aeb3255514247196a2e4f8c1aa6172e6c2153..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessor/Create.php
+++ /dev/null
@@ -1,86 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessor.Create API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_create_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => false
-	);
-	$spec['title'] = array(
-		'title' => E::ts('Title'),
-		'type' => CRM_Utils_Type::T_STRING,
-		'api.required' => true
-	);
-  $spec['name'] = array(
-    'title' => E::ts('Name'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => true
-  );
-  $spec['type'] = array(
-    'title' => E::ts('Type'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => true
-  );
-	$spec['is_active'] = array(
-		'title' => E::ts('Is active'),
-		'type' => CRM_Utils_Type::T_BOOLEAN,
-		'api.required' => true,
-		'api.default' => true,
-	);
-	$spec['description'] = array(
-		'title' => E::ts('Description'),
-		'type' => CRM_Utils_Type::T_TEXT,
-		'api.required' => false,
-	);
-  $spec['configuration'] = array(
-    'title' => E::ts('Configuration'),
-    'type' => CRM_Utils_Type::T_TEXT,
-    'api.required' => false,
-  );
-  $spec['aggregation'] = array(
-    'title' => E::ts('Aggregation'),
-    'type' => CRM_Utils_Type::T_TEXT,
-    'api.required' => false,
-  );
-  $spec['storage_type'] = array(
-    'title' => E::ts('Storage Type'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => false
-  );
-  $spec['storage_configuration'] = array(
-    'title' => E::ts('Storage Configuration'),
-    'type' => CRM_Utils_Type::T_TEXT,
-    'api.required' => false,
-  );
-}
-
-/**
- * DataProcessor.Create API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- *
- *
- */
-function civicrm_api3_data_processor_create($params) {
-  if (!isset($params['id']) && empty($params['title'])) {
-    return civicrm_api3_create_error('Title can not be empty when adding a new DataProcessor');
-  }
-
-  $returnValue = CRM_Dataprocessor_BAO_DataProcessor::add($params);
-	$returnValues[$returnValue['id']] = $returnValue;
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessor', 'Create');
-}
-
diff --git a/api/v3/DataProcessor/Delete.php b/api/v3/DataProcessor/Delete.php
deleted file mode 100644
index f47bb1f85f0a35cbd89c326829de91ab3081ee20..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessor/Delete.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessorSource.Delete API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_source_Delete_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => true
-	);
-}
-
-/**
- * DataProcessor.Delete API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_source_Delete($params) {
-  if (!array_key_exists('id', $params) || empty($params['id'])) {
-    throw new API_Exception('Parameter id is mandatory and can not be empty in ' . __METHOD__, 0010);
-  } else {
-    return civicrm_api3_create_success(CRM_Dataprocessor_BAO_Source::deleteWithId($params['id']), $params, 'DataProcessorSource', 'Delete');
-  }
-}
-
diff --git a/api/v3/DataProcessor/Get.php b/api/v3/DataProcessor/Get.php
deleted file mode 100644
index aab928b7534619ae13617493280efcef57017300..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessor/Get.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * DataProcessor.Get API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_get($params) {
-  $returnValues = CRM_Dataprocessor_BAO_DataProcessor::getValues($params);
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessor', 'Get');
-}
-
-/**
- * DataProcessor.Get API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_get_spec(&$spec) {
-	$fields = CRM_Dataprocessor_BAO_DataProcessor::fields();
-	foreach($fields as $fieldname => $field) {
-		$spec[$fieldname] = $field;
-	}
-}
-
diff --git a/api/v3/DataProcessor/Import.mgd.php b/api/v3/DataProcessor/Import.mgd.php
deleted file mode 100644
index c3b7bf019ec458a5577e877b3f7f4df71139c03c..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessor/Import.mgd.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-// This file declares a managed database record of type "Job".
-// The record will be automatically inserted, updated, or deleted from the
-// database as appropriate. For more details, see "hook_civicrm_managed" at:
-// http://wiki.civicrm.org/confluence/display/CRMDOC42/Hook+Reference
-return array (
-  0 => 
-  array (
-    'name' => 'Cron:DataProcessor.Import',
-    'entity' => 'Job',
-    'params' => 
-    array (
-      'version' => 3,
-      'name' => 'Import Data Processors',
-      'description' => 'Updates the data processor(s) from source files. Run this job manually if you want to update your changes into the database.',
-      'run_frequency' => 'Daily',
-      'api_entity' => 'DataProcessor',
-      'api_action' => 'Import',
-      'parameters' => '',
-    ),
-  ),
-);
diff --git a/api/v3/DataProcessor/Import.php b/api/v3/DataProcessor/Import.php
deleted file mode 100644
index b1fb4fbf9c0ea52c567a5669afbfe960b389e52f..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessor/Import.php
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessor.Import API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_Import_spec(&$spec) {
-}
-
-/**
- * DataProcessor.Import API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_Import($params) {
-  $returnValues = array();
-  $returnValues['import'] = CRM_Dataprocessor_Utils_Importer::importFromExtensions();
-  $returnValues['is_error'] = 0;
-  return $returnValues;
-}
diff --git a/api/v3/DataProcessorField.php b/api/v3/DataProcessorField.php
new file mode 100644
index 0000000000000000000000000000000000000000..bf5161cfe890949a5044d12f38d6bd7d617c6f5d
--- /dev/null
+++ b/api/v3/DataProcessorField.php
@@ -0,0 +1,129 @@
+<?php
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+/**
+ * DataProcessorField.create API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function _civicrm_api3_data_processor_field_create_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessorField::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+    if ($fieldname != 'id' && isset($field['required']) && $field['required']) {
+      $spec[$fieldname]['api.required'] = true;
+    }
+  }
+}
+
+/**
+ * DataProcessorField.create API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_field_create($params) {
+  if (!isset($params['weight']) && !isset($params['id'])) {
+    $params['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Dataprocessor_DAO_DataProcessorField', array('data_processor_id' => $params['data_processor_id']));
+  }
+  $id = null;
+  if (isset($params['id'])) {
+    $id = $params['id'];
+  }
+  $name = null;
+  if (isset($params['name'])) {
+    $name = $params['name'];
+  }
+  $params['name'] = CRM_Dataprocessor_BAO_DataProcessorField::checkName($params['title'], $params['data_processor_id'], $id, $name);
+  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessorField.delete API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_field_delete($params) {
+  return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessorField.get API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function civicrm_api3_data_processor_field_get_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessorField::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+  }
+}
+
+/**
+ * DataProcessorField.get API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_field_get($params) {
+  if (!isset($params['options']) || !isset($params['options']['sort'])) {
+    $params['options']['sort'] = 'weight ASC';
+  }
+  $return = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  foreach($return['values'] as $id => $value) {
+    if (isset($value['configuration'])) {
+      $return['values'][$id]['configuration'] = json_decode($value['configuration'], TRUE);
+    } else {
+      $return['values'][$id]['configuration'] = array();
+    }
+  }
+  return $return;
+}
+
+/**
+ * DataProcessorField.check_name API specification
+ *
+ * @param $params
+ */
+function _civicrm_api3_data_processor_field_check_name_spec($params) {
+  $params['id'] = array(
+    'name' => 'id',
+    'title' => E::ts('ID'),
+  );
+  $params['title'] = array(
+    'name' => 'title',
+    'title' => E::ts('Title'),
+    'api.required' => true,
+  );
+  $params['data_processor_id'] = array(
+    'name' => 'data_processor_id',
+    'title' => E::ts('Data Processor Id'),
+    'api.required' => true,
+  );
+  $params['name'] = array(
+    'name' => 'name',
+    'title' => E::ts('Name'),
+  );
+}
+
+/**
+ * DataProcessorField.check_name API
+ *
+ * @param $params
+ */
+function civicrm_api3_data_processor_field_check_name($params) {
+  $name = CRM_Dataprocessor_BAO_DataProcessorField::checkName($params['title'], $params['data_processor_id'], $params['id'], $params['name']);
+  return array(
+    'name' => $name,
+  );
+}
diff --git a/api/v3/DataProcessorField/Create.php b/api/v3/DataProcessorField/Create.php
deleted file mode 100644
index 48d851fe6124c33509bff0cff00cabf8c8f0975e..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorField/Create.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessorField.Create API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_field_create_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => false
-	);
-  $spec['weight'] = array(
-    'title' => E::ts('Weight'),
-    'type' => CRM_Utils_Type::T_INT,
-    'api.required' => false
-  );
-  $spec['data_processor_id'] = array(
-    'title' => E::ts('Data Processor ID'),
-    'type' => CRM_Utils_Type::T_INT,
-    'api.required' => true,
-  );
-  $spec['type'] = array(
-    'title' => E::ts('Type'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => true
-  );
-  $spec['name'] = array(
-    'title' => E::ts('Name'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => true
-  );
-	$spec['title'] = array(
-		'title' => E::ts('Title'),
-		'type' => CRM_Utils_Type::T_STRING,
-		'api.required' => true
-	);
-	$spec['configuration'] = array(
-    'title' => E::ts('Configuration'),
-    'type' => CRM_Utils_Type::T_TEXT,
-    'api.required' => false,
-	);
-}
-
-/**
- * DataProcessorField.Create API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- *
- *
- */
-function civicrm_api3_data_processor_field_create($params) {
-  $returnValue = CRM_Dataprocessor_BAO_Field::add($params);
-	$returnValues[$returnValue['id']] = $returnValue;
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessorField', 'Create');
-}
-
diff --git a/api/v3/DataProcessorField/Delete.php b/api/v3/DataProcessorField/Delete.php
deleted file mode 100644
index 3b014fa1b9c3b7b8b3ac5e9e3e216d1a00c5df27..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorField/Delete.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessorField.Delete API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_field_Delete_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => true
-	);
-}
-
-/**
- * DataProcessorField.Delete API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_field_Delete($params) {
-  if (!array_key_exists('id', $params) || empty($params['id'])) {
-    throw new API_Exception('Parameter id is mandatory and can not be empty in ' . __METHOD__, 0010);
-  } else {
-    return civicrm_api3_create_success(CRM_Dataprocessor_BAO_DataProcessorField::deleteWithId($params['id']), $params, 'DataProcessorField', 'Delete');
-  }
-}
-
diff --git a/api/v3/DataProcessorField/Get.php b/api/v3/DataProcessorField/Get.php
deleted file mode 100644
index dca751587053ccce90a5b2bd79180dcec785d555..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorField/Get.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * DataProcessorField.Get API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_field_get($params) {
-  $returnValues = CRM_Dataprocessor_BAO_Field::getValues($params);
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessorField', 'Get');
-}
-
-/**
- * DataProcessorField.Get API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_field_get_spec(&$spec) {
-	$fields = CRM_Dataprocessor_BAO_Field::fields();
-	foreach($fields as $fieldname => $field) {
-		$spec[$fieldname] = $field;
-	}
-}
-
diff --git a/api/v3/DataProcessorFilter.php b/api/v3/DataProcessorFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..217626d637cfea452d31c1dde4f6ad21adfc6acb
--- /dev/null
+++ b/api/v3/DataProcessorFilter.php
@@ -0,0 +1,128 @@
+<?php
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+/**
+ * DataProcessorFilter.create API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function _civicrm_api3_data_processor_filter_create_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessorFilter::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+    if ($fieldname != 'id' && isset($field['required']) && $field['required']) {
+      $spec[$fieldname]['api.required'] = true;
+    }
+  }
+}
+
+/**
+ * DataProcessorFilter.create API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_filter_create($params) {
+  if (!isset($params['weight']) && !isset($params['id'])) {
+    $params['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Dataprocessor_DAO_DataProcessorFilter', array('data_processor_id' => $params['data_processor_id']));
+  }
+  $id = null;
+  if (isset($params['id'])) {
+    $id = $params['id'];
+  }
+  $name = null;
+  if (isset($params['name'])) {
+    $name = $params['name'];
+  }
+  $params['name'] = CRM_Dataprocessor_BAO_DataProcessorFilter::checkName($params['title'], $params['data_processor_id'], $id, $name);
+  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessorFilter.delete API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_filter_delete($params) {
+  return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessorFilter.get API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function civicrm_api3_data_processor_filter_get_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessorFilter::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+  }
+}
+
+/**
+ * DataProcessorFilter.get API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_filter_get($params) {
+  if (!isset($params['options']) || !isset($params['options']['sort'])) {
+    $params['options']['sort'] = 'weight ASC';
+  }
+  $return = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  foreach($return['values'] as $id => $value) {
+    if (isset($value['configuration'])) {
+      $return['values'][$id]['configuration'] = json_decode($value['configuration'], TRUE);
+    }
+  }
+  return $return;
+}
+
+
+/**
+ * DataProcessorFilter.check_name API specification
+ *
+ * @param $params
+ */
+function _civicrm_api3_data_processor_filter_check_name_spec($params) {
+  $params['id'] = array(
+    'name' => 'id',
+    'title' => E::ts('ID'),
+  );
+  $params['title'] = array(
+    'name' => 'title',
+    'title' => E::ts('Title'),
+    'api.required' => true,
+  );
+  $params['data_processor_id'] = array(
+    'name' => 'data_processor_id',
+    'title' => E::ts('Data Processor Id'),
+    'api.required' => true,
+  );
+  $params['name'] = array(
+    'name' => 'name',
+    'title' => E::ts('Name'),
+  );
+}
+
+/**
+ * DataProcessorFilter.check_name API
+ *
+ * @param $params
+ */
+function civicrm_api3_data_processor_filter_check_name($params) {
+  $name = CRM_Dataprocessor_BAO_DataProcessorFilter::checkName($params['title'], $params['data_processor_id'], $params['id'], $params['name']);
+  return array(
+    'name' => $name,
+  );
+}
diff --git a/api/v3/DataProcessorFilter/Create.php b/api/v3/DataProcessorFilter/Create.php
deleted file mode 100644
index f20d05d4a843deca67940a12b5af3b55d0ab2e4e..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorFilter/Create.php
+++ /dev/null
@@ -1,67 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessorFilter.Create API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of filters supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_filter_create_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => false
-	);
-  $spec['data_processor_id'] = array(
-    'title' => E::ts('Data Processor ID'),
-    'type' => CRM_Utils_Type::T_INT,
-    'api.required' => true,
-  );
-  $spec['is_required'] = array(
-    'title' => E::ts('Is required'),
-    'type' => CRM_Utils_Type::T_BOOLEAN,
-    'api.required' => true,
-    'api.default' => true,
-  );
-  $spec['type'] = array(
-    'title' => E::ts('Type'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => true
-  );
-  $spec['name'] = array(
-    'title' => E::ts('Name'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => true
-  );
-	$spec['title'] = array(
-		'title' => E::ts('Title'),
-		'type' => CRM_Utils_Type::T_STRING,
-		'api.required' => true
-	);
-	$spec['configuration'] = array(
-    'title' => E::ts('Configuration'),
-    'type' => CRM_Utils_Type::T_TEXT,
-    'api.required' => false,
-	);
-}
-
-/**
- * DataProcessorFilter.Create API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- *
- *
- */
-function civicrm_api3_data_processor_filter_create($params) {
-  $returnValue = CRM_Dataprocessor_BAO_Filter::add($params);
-	$returnValues[$returnValue['id']] = $returnValue;
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessorFilter', 'Create');
-}
-
diff --git a/api/v3/DataProcessorFilter/Delete.php b/api/v3/DataProcessorFilter/Delete.php
deleted file mode 100644
index fdcb3341cb7c3ea22bcf5e43eef1fc8061bed011..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorFilter/Delete.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessorFilter.Delete API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_filter_Delete_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => true
-	);
-}
-
-/**
- * DataProcessorFilter.Delete API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_filter_Delete($params) {
-  if (!array_key_exists('id', $params) || empty($params['id'])) {
-    throw new API_Exception('Parameter id is mandatory and can not be empty in ' . __METHOD__, 0010);
-  } else {
-    return civicrm_api3_create_success(CRM_Dataprocessor_BAO_DataProcessorFilter::deleteWithId($params['id']), $params, 'DataProcessorFilter', 'Delete');
-  }
-}
-
diff --git a/api/v3/DataProcessorFilter/Get.php b/api/v3/DataProcessorFilter/Get.php
deleted file mode 100644
index dbdfd8a54534e04b208dfd351ecb1d08fc09808d..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorFilter/Get.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * DataProcessorFilter.Get API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_filter_get($params) {
-  $returnValues = CRM_Dataprocessor_BAO_Filter::getValues($params);
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessorFilter', 'Get');
-}
-
-/**
- * DataProcessorFilter.Get API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_filter_get_spec(&$spec) {
-	$fields = CRM_Dataprocessor_BAO_Filter::fields();
-	foreach($fields as $fieldname => $field) {
-		$spec[$fieldname] = $field;
-	}
-}
-
diff --git a/api/v3/DataProcessorOutput.php b/api/v3/DataProcessorOutput.php
new file mode 100644
index 0000000000000000000000000000000000000000..79a33215f93c9c08d38153ad30a519bff39aefa1
--- /dev/null
+++ b/api/v3/DataProcessorOutput.php
@@ -0,0 +1,76 @@
+<?php
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+/**
+ * DataProcessorOutput.create API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function _civicrm_api3_data_processor_output_create_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessorOutput::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+    if ($fieldname != 'id' && isset($field['required']) && $field['required']) {
+      $spec[$fieldname]['api.required'] = true;
+    }
+  }
+}
+
+/**
+ * DataProcessorOutput.create API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_output_create($params) {
+  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessorOutput.delete API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_output_delete($params) {
+  return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessorOutput.get API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function civicrm_api3_data_processor_output_get_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessorOutput::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+  }
+}
+
+/**
+ * DataProcessorOutput.get API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_output_get($params) {
+  $return = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  foreach($return['values'] as $id => $value) {
+    if (isset($value['configuration'])) {
+      $return['values'][$id]['configuration'] = json_decode($value['configuration'], TRUE);
+    } else {
+      $return['values'][$id]['configuration'] = array();
+    }
+  }
+  return $return;
+}
diff --git a/api/v3/DataProcessorOutput/Create.php b/api/v3/DataProcessorOutput/Create.php
deleted file mode 100644
index a217729fe86aa5547d76ed49f7427d65d2e61de5..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorOutput/Create.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessorOutput.Create API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_output_create_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => false
-	);
-  $spec['data_processor_id'] = array(
-    'title' => E::ts('Data Processor ID'),
-    'type' => CRM_Utils_Type::T_INT,
-    'api.required' => true,
-  );
-  $spec['type'] = array(
-    'title' => E::ts('Type'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => true
-  );
-	$spec['title'] = array(
-		'title' => E::ts('Title'),
-		'type' => CRM_Utils_Type::T_STRING,
-		'api.required' => true
-	);
-	$spec['configuration'] = array(
-    'title' => E::ts('Description'),
-    'type' => CRM_Utils_Type::T_TEXT,
-    'api.required' => false,
-	);
-  $spec['permission'] = array(
-    'name' => 'permission',
-    'title' => E::ts('Permission'),
-    'type' => CRM_Utils_Type::T_STRING
-  );
-  $spec['api_entity'] = array(
-    'name' => 'api_entity',
-    'title' => E::ts('API Entity'),
-    'type' => CRM_Utils_Type::T_STRING
-  );
-  $spec['api_action'] = array(
-    'name' => 'api_action',
-    'title' => E::ts('API Action name'),
-    'type' => CRM_Utils_Type::T_STRING
-  );
-  $spec['api_count_action'] = array(
-    'name' => 'api_count_action',
-    'title' => E::ts('API GetCount Action name'),
-    'type' => CRM_Utils_Type::T_STRING
-  );
-}
-
-/**
- * DataProcessorOutput.Create API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- *
- *
- */
-function civicrm_api3_data_processor_output_create($params) {
-  $returnValue = CRM_Dataprocessor_BAO_Output::add($params);
-	$returnValues[$returnValue['id']] = $returnValue;
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessorOutput', 'Create');
-}
-
diff --git a/api/v3/DataProcessorOutput/Delete.php b/api/v3/DataProcessorOutput/Delete.php
deleted file mode 100644
index 35dd1e3a46d7d05ab325f8687d59065980cca492..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorOutput/Delete.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessor.Delete API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_Delete_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => true
-	);
-}
-
-/**
- * DataProcessor.Delete API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_Delete($params) {
-  if (!array_key_exists('id', $params) || empty($params['id'])) {
-    throw new API_Exception('Parameter id is mandatory and can not be empty in ' . __METHOD__, 0010);
-  } else {
-    return civicrm_api3_create_success(CRM_Dataprocessor_BAO_DataProcessor::deleteWithId($params['id']), $params, 'DataProcessor', 'Delete');
-  }
-}
-
diff --git a/api/v3/DataProcessorOutput/Get.php b/api/v3/DataProcessorOutput/Get.php
deleted file mode 100644
index 7e5d5341c1164536e9b8dade2b80c863ce9e45ae..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorOutput/Get.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * DataProcessorOutput.Get API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_output_get($params) {
-  $returnValues = CRM_Dataprocessor_BAO_Output::getValues($params);
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessorOutput', 'Get');
-}
-
-/**
- * DataProcessorOutput.Get API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_output_get_spec(&$spec) {
-	$fields = CRM_Dataprocessor_BAO_Output::fields();
-	foreach($fields as $fieldname => $field) {
-		$spec[$fieldname] = $field;
-	}
-}
-
diff --git a/api/v3/DataProcessorSource.php b/api/v3/DataProcessorSource.php
new file mode 100644
index 0000000000000000000000000000000000000000..a73f883db48d8e75bae9f1ef2f531bd043c672b8
--- /dev/null
+++ b/api/v3/DataProcessorSource.php
@@ -0,0 +1,136 @@
+<?php
+use CRM_Dataprocessor_ExtensionUtil as E;
+
+/**
+ * DataProcessorSource.create API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function _civicrm_api3_data_processor_source_create_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessorSource::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+    if ($fieldname != 'id' && isset($field['required']) && $field['required']) {
+      $spec[$fieldname]['api.required'] = true;
+    }
+  }
+}
+
+/**
+ * DataProcessorSource.create API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_source_create($params) {
+  if (!isset($params['weight']) && !isset($params['id'])) {
+    $params['weight'] = CRM_Utils_Weight::getDefaultWeight('CRM_Dataprocessor_DAO_DataProcessorSource', array('data_processor_id' => $params['data_processor_id']));
+  }
+  $id = null;
+  if (isset($params['id'])) {
+    $id = $params['id'];
+  }
+  $name = null;
+  if (isset($params['name'])) {
+    $name = $params['name'];
+  }
+  $params['name'] = CRM_Dataprocessor_BAO_DataProcessorSource::checkName($params['title'], $params['data_processor_id'], $id, $name);
+  return _civicrm_api3_basic_create(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessorSource.delete API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_source_delete($params) {
+  return _civicrm_api3_basic_delete(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+}
+
+/**
+ * DataProcessorSource.get API specification (optional)
+ * This is used for documentation and validation.
+ *
+ * @param array $spec description of fields supported by this API call
+ * @return void
+ * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
+ */
+function civicrm_api3_data_processor_source_get_spec(&$spec) {
+  $fields = CRM_Dataprocessor_DAO_DataProcessorSource::fields();
+  foreach($fields as $fieldname => $field) {
+    $spec[$fieldname] = $field;
+  }
+}
+
+/**
+ * DataProcessorSource.get API
+ *
+ * @param array $params
+ * @return array API result descriptor
+ * @throws API_Exception
+ */
+function civicrm_api3_data_processor_source_get($params) {
+  if (!isset($params['options']) || !isset($params['options']['sort'])) {
+    $params['options']['sort'] = 'weight ASC';
+  }
+  $return = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
+  foreach($return['values'] as $id => $value) {
+    if (isset($value['configuration'])) {
+      $return['values'][$id]['configuration'] = json_decode($value['configuration'], TRUE);
+    } else {
+      $return['values'][$id]['configuration'] = array();
+    }
+    if (isset($value['join_configuration'])) {
+      $return['values'][$id]['join_configuration'] = json_decode($value['join_configuration'], TRUE);
+    } else {
+      $return['values'][$id]['join_configuration'] = array();
+    }
+  }
+  return $return;
+}
+
+
+/**
+ * DataProcessorSource.check_name API specification
+ *
+ * @param $params
+ */
+function _civicrm_api3_data_processor_source_check_name_spec($params) {
+  $params['id'] = array(
+    'name' => 'id',
+    'title' => E::ts('ID'),
+  );
+  $params['title'] = array(
+    'name' => 'title',
+    'title' => E::ts('Title'),
+    'api.required' => true,
+  );
+  $params['data_processor_id'] = array(
+    'name' => 'data_processor_id',
+    'title' => E::ts('Data Processor Id'),
+    'api.required' => true,
+  );
+  $params['name'] = array(
+    'name' => 'name',
+    'title' => E::ts('Name'),
+  );
+}
+
+/**
+ * DataProcessorSource.check_name API
+ *
+ * @param $params
+ */
+function civicrm_api3_data_processor_source_check_name($params) {
+  $name = CRM_Dataprocessor_BAO_DataProcessorSource::checkName($params['title'], $params['data_processor_id'], $params['id'], $params['name']);
+  return array(
+    'name' => $name,
+  );
+}
+
diff --git a/api/v3/DataProcessorSource/Create.php b/api/v3/DataProcessorSource/Create.php
deleted file mode 100644
index 49f438735a74954616506cdb777126679121ba49..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorSource/Create.php
+++ /dev/null
@@ -1,71 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessorSource.Create API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_source_create_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => false
-	);
-  $spec['data_processor_id'] = array(
-    'title' => E::ts('Data Processor ID'),
-    'type' => CRM_Utils_Type::T_INT,
-    'api.required' => true,
-  );
-  $spec['type'] = array(
-    'title' => E::ts('Type'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => true
-  );
-  $spec['name'] = array(
-    'title' => E::ts('Name'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => true
-  );
-	$spec['title'] = array(
-		'title' => E::ts('Title'),
-		'type' => CRM_Utils_Type::T_STRING,
-		'api.required' => true
-	);
-	$spec['configuration'] = array(
-    'title' => E::ts('Configuration'),
-    'type' => CRM_Utils_Type::T_TEXT,
-    'api.required' => false,
-	);
-  $spec['join_type'] = array(
-    'title' => E::ts('Join Type'),
-    'type' => CRM_Utils_Type::T_STRING,
-    'api.required' => false
-  );
-  $spec['join_configuration'] = array(
-    'title' => E::ts('Join Configuration'),
-    'type' => CRM_Utils_Type::T_TEXT,
-    'api.required' => false,
-  );
-}
-
-/**
- * DataProcessorSource.Create API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- *
- *
- */
-function civicrm_api3_data_processor_source_create($params) {
-  $returnValue = CRM_Dataprocessor_BAO_Source::add($params);
-	$returnValues[$returnValue['id']] = $returnValue;
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessorSource', 'Create');
-}
-
diff --git a/api/v3/DataProcessorSource/Delete.php b/api/v3/DataProcessorSource/Delete.php
deleted file mode 100644
index 35dd1e3a46d7d05ab325f8687d59065980cca492..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorSource/Delete.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-use CRM_Dataprocessor_ExtensionUtil as E;
-
-/**
- * DataProcessor.Delete API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRMDOC/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_Delete_spec(&$spec) {
-  $spec['id'] = array(
-		'title' => E::ts('ID'),
-		'type' => CRM_Utils_Type::T_INT,
-		'api.required' => true
-	);
-}
-
-/**
- * DataProcessor.Delete API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_Delete($params) {
-  if (!array_key_exists('id', $params) || empty($params['id'])) {
-    throw new API_Exception('Parameter id is mandatory and can not be empty in ' . __METHOD__, 0010);
-  } else {
-    return civicrm_api3_create_success(CRM_Dataprocessor_BAO_DataProcessor::deleteWithId($params['id']), $params, 'DataProcessor', 'Delete');
-  }
-}
-
diff --git a/api/v3/DataProcessorSource/Get.php b/api/v3/DataProcessorSource/Get.php
deleted file mode 100644
index b317c9ceb23404c34bd2db8310a249452395bf4b..0000000000000000000000000000000000000000
--- a/api/v3/DataProcessorSource/Get.php
+++ /dev/null
@@ -1,30 +0,0 @@
-<?php
-/**
- * DataProcessorSource.Get API
- *
- * @param array $params
- * @return array API result descriptor
- * @see civicrm_api3_create_success
- * @see civicrm_api3_create_error
- * @throws API_Exception
- */
-function civicrm_api3_data_processor_source_get($params) {
-  $returnValues = CRM_Dataprocessor_BAO_Source::getValues($params);
-  return civicrm_api3_create_success($returnValues, $params, 'DataProcessorSource', 'Get');
-}
-
-/**
- * DataProcessorSource.Get API specification (optional)
- * This is used for documentation and validation.
- *
- * @param array $spec description of fields supported by this API call
- * @return void
- * @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
- */
-function _civicrm_api3_data_processor_source_get_spec(&$spec) {
-	$fields = CRM_Dataprocessor_BAO_Source::fields();
-	foreach($fields as $fieldname => $field) {
-		$spec[$fieldname] = $field;
-	}
-}
-
diff --git a/dataprocessor.civix.php b/dataprocessor.civix.php
index 991bfade3f8e161cdcc06c2798f96d8f26d94f07..b4cbf227932589c2da71f7a2ad05218a89cfcefc 100644
--- a/dataprocessor.civix.php
+++ b/dataprocessor.civix.php
@@ -263,16 +263,17 @@ function _dataprocessor_civix_find_files($dir, $pattern) {
  */
 function _dataprocessor_civix_civicrm_managed(&$entities) {
   $mgdFiles = _dataprocessor_civix_find_files(__DIR__, '*.mgd.php');
+  sort($mgdFiles);
   foreach ($mgdFiles as $file) {
     $es = include $file;
     foreach ($es as $e) {
       if (empty($e['module'])) {
         $e['module'] = E::LONG_NAME;
       }
-      $entities[] = $e;
       if (empty($e['params']['version'])) {
         $e['params']['version'] = '3';
       }
+      $entities[] = $e;
     }
   }
 }
@@ -456,5 +457,35 @@ function _dataprocessor_civix_civicrm_alterSettingsFolders(&$metaDataFolders = N
 
 function _dataprocessor_civix_civicrm_entityTypes(&$entityTypes) {
   $entityTypes = array_merge($entityTypes, array (
+    'CRM_Dataprocessor_DAO_DataProcessor' => 
+    array (
+      'name' => 'DataProcessor',
+      'class' => 'CRM_Dataprocessor_DAO_DataProcessor',
+      'table' => 'civicrm_data_processor',
+    ),
+    'CRM_Dataprocessor_DAO_DataProcessorField' => 
+    array (
+      'name' => 'DataProcessorField',
+      'class' => 'CRM_Dataprocessor_DAO_DataProcessorField',
+      'table' => 'civicrm_data_processor_field',
+    ),
+    'CRM_Dataprocessor_DAO_DataProcessorFilter' => 
+    array (
+      'name' => 'DataProcessorFilter',
+      'class' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+      'table' => 'civicrm_data_processor_filter',
+    ),
+    'CRM_Dataprocessor_DAO_DataProcessorOutput' => 
+    array (
+      'name' => 'DataProcessorOutput',
+      'class' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+      'table' => 'civicrm_data_processor_output',
+    ),
+    'CRM_Dataprocessor_DAO_DataProcessorSource' => 
+    array (
+      'name' => 'DataProcessorSource',
+      'class' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+      'table' => 'civicrm_data_processor_source',
+    ),
   ));
 }
diff --git a/docs/hooks.md b/docs/hooks.md
new file mode 100644
index 0000000000000000000000000000000000000000..abb29d198bdc2d062db2f89ce20ff3a9ac03f5da
--- /dev/null
+++ b/docs/hooks.md
@@ -0,0 +1,3 @@
+# Available Hooks
+
+## hook_civicrm_dataprocessor_export
\ No newline at end of file
diff --git a/sql/alter.sql b/sql/alter.sql
new file mode 100644
index 0000000000000000000000000000000000000000..0409524f0f58839e7457c0cf39d25f71a6f6d16a
--- /dev/null
+++ b/sql/alter.sql
@@ -0,0 +1,27 @@
+ALTER TABLE `civicrm_data_processor_field`
+CHANGE `name` `name` VARCHAR(255) NOT NULL,
+CHANGE `type` `type` VARCHAR(255) NOT NULL,
+CHANGE `title` `title` VARCHAR(255) NOT NULL;
+
+ALTER TABLE `civicrm_data_processor_filter`
+CHANGE `name` `name` VARCHAR(255) NOT NULL,
+CHANGE `type` `type` VARCHAR(255) NOT NULL,
+CHANGE `title` `title` VARCHAR(255) NOT NULL,
+ADD `weight` int NULL;
+
+UPDATE `civicrm_data_processor_filter` SET `weight` = `id`;
+
+ALTER TABLE `civicrm_data_processor_source`
+CHANGE `name` `name` VARCHAR(255) NOT NULL,
+CHANGE `type` `type` VARCHAR(255) NOT NULL,
+CHANGE `title` `title` VARCHAR(255) NOT NULL,
+CHANGE `join_type` `join_type` VARCHAR(255) NULL,
+ADD `weight` int NULL;
+
+UPDATE `civicrm_data_processor_source` SET `weight` = `id`;
+
+ALTER TABLE `civicrm_data_processor_filter`
+CHANGE `name` `name` VARCHAR(255) NOT NULL,
+CHANGE `type` `type` VARCHAR(255) NOT NULL,
+CHANGE `title` `title` VARCHAR(255) NOT NULL,
+CHANGE `storage_type` `storage_type` VARCHAR(255) NULL;
\ No newline at end of file
diff --git a/sql/auto_install.sql b/sql/auto_install.sql
new file mode 100644
index 0000000000000000000000000000000000000000..8de37b3528bf1481772a3479ca4ebbeb7f4ced39
--- /dev/null
+++ b/sql/auto_install.sql
@@ -0,0 +1,197 @@
+-- +--------------------------------------------------------------------+
+-- | CiviCRM version 5                                                  |
+-- +--------------------------------------------------------------------+
+-- | Copyright CiviCRM LLC (c) 2004-2019                                |
+-- +--------------------------------------------------------------------+
+-- | This file is a part of CiviCRM.                                    |
+-- |                                                                    |
+-- | CiviCRM is free software; you can copy, modify, and distribute it  |
+-- | under the terms of the GNU Affero General Public License           |
+-- | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+-- |                                                                    |
+-- | CiviCRM is distributed in the hope that it will be useful, but     |
+-- | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+-- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+-- | See the GNU Affero General Public License for more details.        |
+-- |                                                                    |
+-- | You should have received a copy of the GNU Affero General Public   |
+-- | License and the CiviCRM Licensing Exception along                  |
+-- | with this program; if not, contact CiviCRM LLC                     |
+-- | at info[AT]civicrm[DOT]org. If you have questions about the        |
+-- | GNU Affero General Public License or the licensing of CiviCRM,     |
+-- | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+-- +--------------------------------------------------------------------+
+--
+-- Generated from schema.tpl
+-- DO NOT EDIT.  Generated by CRM_Core_CodeGen
+--
+
+
+-- +--------------------------------------------------------------------+
+-- | CiviCRM version 5                                                  |
+-- +--------------------------------------------------------------------+
+-- | Copyright CiviCRM LLC (c) 2004-2019                                |
+-- +--------------------------------------------------------------------+
+-- | This file is a part of CiviCRM.                                    |
+-- |                                                                    |
+-- | CiviCRM is free software; you can copy, modify, and distribute it  |
+-- | under the terms of the GNU Affero General Public License           |
+-- | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+-- |                                                                    |
+-- | CiviCRM is distributed in the hope that it will be useful, but     |
+-- | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+-- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+-- | See the GNU Affero General Public License for more details.        |
+-- |                                                                    |
+-- | You should have received a copy of the GNU Affero General Public   |
+-- | License and the CiviCRM Licensing Exception along                  |
+-- | with this program; if not, contact CiviCRM LLC                     |
+-- | at info[AT]civicrm[DOT]org. If you have questions about the        |
+-- | GNU Affero General Public License or the licensing of CiviCRM,     |
+-- | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+-- +--------------------------------------------------------------------+
+--
+-- Generated from drop.tpl
+-- DO NOT EDIT.  Generated by CRM_Core_CodeGen
+--
+-- /*******************************************************
+-- *
+-- * Clean up the exisiting tables
+-- *
+-- *******************************************************/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+DROP TABLE IF EXISTS `civicrm_data_processor_source`;
+DROP TABLE IF EXISTS `civicrm_data_processor_output`;
+DROP TABLE IF EXISTS `civicrm_data_processor_filter`;
+DROP TABLE IF EXISTS `civicrm_data_processor_field`;
+DROP TABLE IF EXISTS `civicrm_data_processor`;
+
+SET FOREIGN_KEY_CHECKS=1;
+-- /*******************************************************
+-- *
+-- * Create new tables
+-- *
+-- *******************************************************/
+
+-- /*******************************************************
+-- *
+-- * civicrm_data_processor
+-- *
+-- *******************************************************/
+CREATE TABLE `civicrm_data_processor` (
+
+
+     `id` int unsigned NOT NULL AUTO_INCREMENT  COMMENT 'Unique DataProcessor ID',
+     `name` varchar(255) NULL   ,
+     `title` varchar(255) NOT NULL   ,
+     `type` varchar(255) NOT NULL   ,
+     `configuration` text NULL   ,
+     `aggregation` text NULL   ,
+     `is_active` tinyint NOT NULL   ,
+     `description` text NULL   ,
+     `storage_type` varchar(255) NULL   ,
+     `storage_configuration` text NULL   ,
+     `status` int unsigned NULL  DEFAULT 0 ,
+     `source_file` varchar(255) NULL    
+,
+        PRIMARY KEY (`id`)
+ 
+ 
+ 
+)    ;
+
+-- /*******************************************************
+-- *
+-- * civicrm_data_processor_field
+-- *
+-- *******************************************************/
+CREATE TABLE `civicrm_data_processor_field` (
+
+
+     `id` int unsigned NOT NULL AUTO_INCREMENT  COMMENT 'Unique DataProcessorField ID',
+     `data_processor_id` int unsigned NOT NULL   COMMENT 'FK to Data Processor',
+     `weight` int NULL   ,
+     `name` varchar(255) NULL   ,
+     `title` varchar(255) NOT NULL   ,
+     `type` varchar(255) NOT NULL   ,
+     `configuration` text NULL    
+,
+        PRIMARY KEY (`id`)
+ 
+ 
+,          CONSTRAINT FK_civicrm_data_processor_field_data_processor_id FOREIGN KEY (`data_processor_id`) REFERENCES `civicrm_data_processor`(`id`) ON DELETE CASCADE  
+)    ;
+
+-- /*******************************************************
+-- *
+-- * civicrm_data_processor_filter
+-- *
+-- *******************************************************/
+CREATE TABLE `civicrm_data_processor_filter` (
+
+
+     `id` int unsigned NOT NULL AUTO_INCREMENT  COMMENT 'Unique DataProcessorFilter ID',
+     `data_processor_id` int unsigned NOT NULL   COMMENT 'FK to Data Processor',
+     `weight` int NULL   ,
+     `name` varchar(255) NULL   ,
+     `title` varchar(255) NOT NULL   ,
+     `type` varchar(255) NOT NULL   ,
+     `is_required` tinyint NULL   ,
+     `configuration` text NULL    
+,
+        PRIMARY KEY (`id`)
+ 
+ 
+,          CONSTRAINT FK_civicrm_data_processor_filter_data_processor_id FOREIGN KEY (`data_processor_id`) REFERENCES `civicrm_data_processor`(`id`) ON DELETE CASCADE  
+)    ;
+
+-- /*******************************************************
+-- *
+-- * civicrm_data_processor_output
+-- *
+-- *******************************************************/
+CREATE TABLE `civicrm_data_processor_output` (
+
+
+     `id` int unsigned NOT NULL AUTO_INCREMENT  COMMENT 'Unique DataProcessorOutput ID',
+     `data_processor_id` int unsigned NOT NULL   COMMENT 'FK to Data Processor',
+     `type` varchar(255) NOT NULL   ,
+     `configuration` text NULL   ,
+     `permission` varchar(255) NULL   ,
+     `api_entity` varchar(255) NULL   ,
+     `api_action` varchar(255) NULL   ,
+     `api_count_action` varchar(255) NULL    
+,
+        PRIMARY KEY (`id`)
+ 
+ 
+,          CONSTRAINT FK_civicrm_data_processor_output_data_processor_id FOREIGN KEY (`data_processor_id`) REFERENCES `civicrm_data_processor`(`id`) ON DELETE CASCADE  
+)    ;
+
+-- /*******************************************************
+-- *
+-- * civicrm_data_processor_source
+-- *
+-- *******************************************************/
+CREATE TABLE `civicrm_data_processor_source` (
+
+
+     `id` int unsigned NOT NULL AUTO_INCREMENT  COMMENT 'Unique DataProcessorSource ID',
+     `data_processor_id` int unsigned NOT NULL   COMMENT 'FK to Data Processor',
+     `weight` int NULL   ,
+     `name` varchar(255) NULL   ,
+     `title` varchar(255) NOT NULL   ,
+     `type` varchar(255) NOT NULL   ,
+     `configuration` text NULL   ,
+     `join_type` varchar(255) NULL   ,
+     `join_configuration` text NULL    
+,
+        PRIMARY KEY (`id`)
+ 
+ 
+,          CONSTRAINT FK_civicrm_data_processor_source_data_processor_id FOREIGN KEY (`data_processor_id`) REFERENCES `civicrm_data_processor`(`id`) ON DELETE CASCADE  
+)    ;
+
+ 
diff --git a/sql/auto_uninstall.sql b/sql/auto_uninstall.sql
new file mode 100644
index 0000000000000000000000000000000000000000..5d4ba700faf99bb819dfb1cc8c56c4d71d385c9b
--- /dev/null
+++ b/sql/auto_uninstall.sql
@@ -0,0 +1,42 @@
+-- +--------------------------------------------------------------------+
+-- | CiviCRM version 5                                                  |
+-- +--------------------------------------------------------------------+
+-- | Copyright CiviCRM LLC (c) 2004-2019                                |
+-- +--------------------------------------------------------------------+
+-- | This file is a part of CiviCRM.                                    |
+-- |                                                                    |
+-- | CiviCRM is free software; you can copy, modify, and distribute it  |
+-- | under the terms of the GNU Affero General Public License           |
+-- | Version 3, 19 November 2007 and the CiviCRM Licensing Exception.   |
+-- |                                                                    |
+-- | CiviCRM is distributed in the hope that it will be useful, but     |
+-- | WITHOUT ANY WARRANTY; without even the implied warranty of         |
+-- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               |
+-- | See the GNU Affero General Public License for more details.        |
+-- |                                                                    |
+-- | You should have received a copy of the GNU Affero General Public   |
+-- | License and the CiviCRM Licensing Exception along                  |
+-- | with this program; if not, contact CiviCRM LLC                     |
+-- | at info[AT]civicrm[DOT]org. If you have questions about the        |
+-- | GNU Affero General Public License or the licensing of CiviCRM,     |
+-- | see the CiviCRM license FAQ at http://civicrm.org/licensing        |
+-- +--------------------------------------------------------------------+
+--
+-- Generated from drop.tpl
+-- DO NOT EDIT.  Generated by CRM_Core_CodeGen
+--
+-- /*******************************************************
+-- *
+-- * Clean up the exisiting tables
+-- *
+-- *******************************************************/
+
+SET FOREIGN_KEY_CHECKS=0;
+
+DROP TABLE IF EXISTS `civicrm_data_processor_source`;
+DROP TABLE IF EXISTS `civicrm_data_processor_output`;
+DROP TABLE IF EXISTS `civicrm_data_processor_filter`;
+DROP TABLE IF EXISTS `civicrm_data_processor_field`;
+DROP TABLE IF EXISTS `civicrm_data_processor`;
+
+SET FOREIGN_KEY_CHECKS=1;
diff --git a/sql/create_civicrm_data_processor.sql b/sql/create_civicrm_data_processor.sql
deleted file mode 100644
index 9206836af57b2e9c68f52868d68c813ee4c4c303..0000000000000000000000000000000000000000
--- a/sql/create_civicrm_data_processor.sql
+++ /dev/null
@@ -1,61 +0,0 @@
-CREATE TABLE IF NOT EXISTS `civicrm_data_processor` (
-  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
-  `type` VARCHAR(128) NOT NULL,
-  `configuration` TEXT NULL,
-  `aggregation` TEXT NULL,
-  `name` VARCHAR(128) NOT NULL,
-  `title` VARCHAR(128) NULL,
-  `is_active` TINYINT NULL DEFAULT 1,
-  `description` TEXT NULL,
-  `storage_type` VARCHAR(128) NULL,
-  `storage_configuration` TEXT NULL,
-  `status` TINYINT NULL DEFAULT 1,
-  `source_file` VARCHAR(255) NOT NULL DEFAULT '',
-  PRIMARY KEY (`id`)
-) ENGINE = InnoDB;
-
-CREATE TABLE IF NOT EXISTS `civicrm_data_processor_source` (
-  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
-  `data_processor_id` INT UNSIGNED NOT NULL,
-  `name` VARCHAR(128) NOT NULL,
-  `type` VARCHAR(128) NOT NULL,
-  `title` VARCHAR(128) NOT NULL,
-  `configuration` TEXT NULL,
-  `join_type` VARCHAR(128) NULL,
-  `join_configuration` TEXT NULL,
-  PRIMARY KEY (`id`)
-) ENGINE = InnoDB;
-
-CREATE TABLE IF NOT EXISTS `civicrm_data_processor_filter` (
-  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
-  `data_processor_id` INT UNSIGNED NOT NULL,
-  `name` VARCHAR(128) NOT NULL,
-  `type` VARCHAR(128) NOT NULL,
-  `title` VARCHAR(128) NOT NULL,
-  `is_required` TINYINT NULL DEFAULT 1,
-  `configuration` TEXT NULL,
-  PRIMARY KEY (`id`)
-) ENGINE = InnoDB;
-
-CREATE TABLE IF NOT EXISTS `civicrm_data_processor_field` (
-  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
-  `weight` INT UNSIGNED NOT NULL DEFAULT 0,
-  `data_processor_id` INT UNSIGNED NOT NULL,
-  `name` VARCHAR(128) NOT NULL,
-  `type` VARCHAR(128) NOT NULL,
-  `title` VARCHAR(128) NOT NULL,
-  `configuration` TEXT NULL,
-  PRIMARY KEY (`id`)
-) ENGINE = InnoDB;
-
-CREATE TABLE IF NOT EXISTS `civicrm_data_processor_output` (
-  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
-  `data_processor_id` INT UNSIGNED NOT NULL,
-  `type` VARCHAR(128) NOT NULL,
-  `configuration` TEXT NULL,
-  `permission` VARCHAR(255) NULL,
-  `api_entity` VARCHAR(255) NULL,
-  `api_action` VARCHAR(255) NULL,
-  `api_count_action` VARCHAR(255) NULL,
-  PRIMARY KEY (`id`)
-) ENGINE = InnoDB;
\ No newline at end of file
diff --git a/sql/uninstall.sql b/sql/uninstall.sql
deleted file mode 100644
index ef832e7a17f9b54dad564dc37f3f37349d064464..0000000000000000000000000000000000000000
--- a/sql/uninstall.sql
+++ /dev/null
@@ -1,4 +0,0 @@
-DROP TABLE IF EXISTS `civicrm_data_processor_output`;
-DROP TABLE IF EXISTS `civicrm_data_processor_field`;
-DROP TABLE IF EXISTS `civicrm_data_processor_source`;
-DROP TABLE IF EXISTS `civicrm_data_processor`;
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/DataProcessor.tpl b/templates/CRM/Dataprocessor/Form/DataProcessor.tpl
index deab84407c43b1f5a5baea02cf58fcfcfd4548ff..37fb223c35154a6857a3b2a975a16201444e5c45 100644
--- a/templates/CRM/Dataprocessor/Form/DataProcessor.tpl
+++ b/templates/CRM/Dataprocessor/Form/DataProcessor.tpl
@@ -24,10 +24,19 @@
 <div class="crm-block crm-form-block crm-data-processor_title-block">
   <div class="crm-section">
     <div class="label">{$form.title.label}</div>
-    <div class="content">{$form.title.html}</div>
+    <div class="content">
+      {$form.title.html}
+      <span class="">
+        {ts}System name:{/ts}&nbsp;
+        <span id="systemName" style="font-style: italic;">{if ($dataProcessor)}{$dataProcessor.name}{/if}</span>
+        <a href="javascript:void(0);" onclick="jQuery('#nameSection').removeClass('hiddenElement'); jQuery(this).parent().addClass('hiddenElement'); return false;">
+          {ts}Change{/ts}
+        </a>
+      </span>
+    </div>
     <div class="clear"></div>
   </div>
-  <div class="crm-section">
+  <div id="nameSection" class="crm-section hiddenElement">
     <div class="label">{$form.name.label}</div>
     <div class="content">
       {$form.name.html}
@@ -55,6 +64,26 @@
     {include file="CRM/Dataprocessor/Form/DataProcessorBlocks/Outputs.tpl"}
   {/if}
 
+  <script type="text/javascript">
+    {literal}
+    CRM.$(function($) {
+      var id = {/literal}{if ($dataProcessor)}{$dataProcessor.id}{else}false{/if}{literal};
+
+      $('#title').on('blur', function() {
+        var title = $('#title').val();
+        if ($('#nameSection').hasClass('hiddenElement') && !id) {
+          CRM.api3('DataProcessor', 'check_name', {
+            'title': title
+          }).done(function (result) {
+            $('#systemName').html(result.name);
+            $('#name').val(result.name);
+          });
+        }
+      });
+    });
+    {/literal}
+  </script>
+
 {/if}
 
 <div class="crm-submit-buttons">
diff --git a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Fields.tpl b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Fields.tpl
index e671101c7d22532d38e3671a66bc3e2210fc9cee..c9df525707fd6fc93646ce7e1a7d2e48f89916b8 100644
--- a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Fields.tpl
+++ b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Fields.tpl
@@ -4,8 +4,7 @@
     <table>
         <tr>
             <th>{ts}Title{/ts}</th>
-            <th>{ts}Name{/ts}</th>
-            <th></th>
+            <th>{ts}System Name{/ts}</th>
             <th></th>
             <th></th>
             <th></th>
@@ -13,13 +12,8 @@
         {foreach from=$fields item=field}
             <tr>
                 <td>{$field.title}</td>
-                <td>{$field.name}</td>
-                <td>{$field.weight}</td>
-                <td>
-                    {if $field.configuration_link}
-                        <a href="{$source.configuration_link}">{ts}Configure Field{/ts}</a>
-                    {/if}
-                </td>
+                <td><span class="description">{$field.name}</span></td>
+                <td>{if ($field.weight && !is_numeric($field.weight))}{$field.weight}{/if}</td>
                 <td>
                     <a href="{crmURL p="civicrm/dataprocessor/form/field" q="reset=1&action=update&data_processor_id=`$field.data_processor_id`&id=`$field.id`"}">{ts}Edit{/ts}</a>
                 </td>
diff --git a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Filters.tpl b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Filters.tpl
index fab5d7e0c03b822311d1faa097c95264dcb7594a..90448919304586267405b9cd7e7f0569e9cce235 100644
--- a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Filters.tpl
+++ b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Filters.tpl
@@ -4,22 +4,21 @@
         <table>
             <tr>
                 <th>{ts}Title{/ts}</th>
-                <th>{ts}Name{/ts}</th>
-                <th>{ts}Required{/ts}</th>
+                <th>{ts}System name{/ts}</th>
                 <th></th>
                 <th></th>
                 <th></th>
             </tr>
             {foreach from=$filters item=filter}
                 <tr>
-                    <td>{$filter.title}</td>
-                    <td>{$filter.name}</td>
-                    <td>{$filter.is_required}</td>
                     <td>
-                        {if $filter.configuration_link}
-                            <a href="{$filter.configuration_link}">{ts}Configure Filter{/ts}</a>
+                        {$filter.title}
+                        {if ($filter.is_required)}
+                            <span class="crm-marker">*</span>
                         {/if}
                     </td>
+                    <td><span class="description">{$filter.name}</span></td>
+                    <td>{if ($filter.weight && !is_numeric($filter.weight))}{$filter.weight}{/if}</td>
                     <td>
                         <a href="{crmURL p="civicrm/dataprocessor/form/filter" q="reset=1&action=update&data_processor_id=`$filter.data_processor_id`&id=`$filter.id`"}">{ts}Edit{/ts}</a>
                     </td>
diff --git a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Outputs.tpl b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Outputs.tpl
index 8dac06200f1f2db01eb09559fcbb0c7ce24a0798..34153305ef67b17b0c43828b4d70d3aac84d3315 100644
--- a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Outputs.tpl
+++ b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Outputs.tpl
@@ -6,16 +6,11 @@
             <th>{ts}Output{/ts}</th>
             <th></th>
             <th></th>
-            <th></th>
         </tr>
         {foreach from=$outputs item=output}
             <tr>
                 <td>{$output.type_name}</td>
                 <td>
-                    {if ($output.configuration_link)}
-                        <a href="{$output.configuration_link}">{ts}Configure{/ts}</a>
-                    {/if}
-                </td><td>
                     <a href="{crmURL p="civicrm/dataprocessor/form/output" q="reset=1&action=update&data_processor_id=`$output.data_processor_id`&id=`$output.id`"}">{ts}Edit{/ts}</a>
                 </td><td>
                     <a href="{crmURL p="civicrm/dataprocessor/form/output" q="reset=1&action=delete&data_processor_id=`$output.data_processor_id`&id=`$output.id`"}">{ts}Remove{/ts}</a>
diff --git a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Sources.tpl b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Sources.tpl
index bdc57fe0f8655a4285964cc027aee397697e466a..d2015c853b98c908cd64b77c23e8a3437c45e48d 100644
--- a/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Sources.tpl
+++ b/templates/CRM/Dataprocessor/Form/DataProcessorBlocks/Sources.tpl
@@ -8,22 +8,12 @@
             <th></th>
             <th></th>
             <th></th>
-            <th></th>
         </tr>
         {foreach from=$sources item=source}
             <tr>
                 <td>{$source.type_name}</td>
                 <td>{$source.title}</td>
-                <td>
-                    {if $source.join_link}
-                        <a href="{$source.join_link}">{ts}Join Configuration{/ts}</a>
-                    {/if}
-                </td>
-                <td>
-                    {if $source.configuration_link}
-                        <a href="{$source.configuration_link}">{ts}Configure source{/ts}</a>
-                    {/if}
-                </td>
+                <td>{if ($source.weight && !is_numeric($source.weight))}{$source.weight}{/if}</td>
                 <td>
                     <a href="{crmURL p="civicrm/dataprocessor/form/source" q="reset=1&action=update&data_processor_id=`$source.data_processor_id`&id=`$source.id`"}">{ts}Edit{/ts}</a>
                 </td>
diff --git a/templates/CRM/Dataprocessor/Form/Field.tpl b/templates/CRM/Dataprocessor/Form/Field.tpl
index 711b32c77977fbeda6f5e991cc37bc804b876c9f..c46b6b8912c2a2d4244adb5c38356db18e4b18a8 100644
--- a/templates/CRM/Dataprocessor/Form/Field.tpl
+++ b/templates/CRM/Dataprocessor/Form/Field.tpl
@@ -21,15 +21,46 @@
         </div>
         <div class="crm-section">
             <div class="label">{$form.title.label}</div>
-            <div class="content">{$form.title.html}</div>
+            <div class="content">
+                {$form.title.html}
+                <span class="">
+                {ts}System name:{/ts}&nbsp;
+                <span id="systemName" style="font-style: italic;">{if ($field)}{$field.name}{/if}</span>
+                <a href="javascript:void(0);" onclick="jQuery('#nameSection').removeClass('hiddenElement'); jQuery(this).parent().addClass('hiddenElement'); return false;">
+                  {ts}Change{/ts}
+                </a>
+                </span>
+            </div>
             <div class="clear"></div>
         </div>
-        <div class="crm-section">
+        <div id="nameSection" class="crm-section hiddenElement">
             <div class="label">{$form.name.label}</div>
             <div class="content">{$form.name.html}</div>
             <div class="clear"></div>
         </div>
     </div>
+
+    <script type="text/javascript">
+        {literal}
+        CRM.$(function($) {
+          var id = {/literal}{if ($field)}{$field.id}{else}false{/if}{literal};
+          var data_processor_id = {/literal}{$data_processor_id}{literal};
+
+          $('#title').on('blur', function() {
+            var title = $('#title').val();
+            if ($('#nameSection').hasClass('hiddenElement') && !id) {
+              CRM.api3('DataProcessorField', 'check_name', {
+                'title': title,
+                'data_processor_id': data_processor_id
+              }).done(function (result) {
+                $('#systemName').html(result.name);
+                $('#name').val(result.name);
+              });
+            }
+          });
+        });
+        {/literal}
+    </script>
 {/if}
 
 <div class="crm-submit-buttons">
diff --git a/templates/CRM/Dataprocessor/Form/Filter.tpl b/templates/CRM/Dataprocessor/Form/Filter.tpl
index b3afbc13dee646a041b58b28b785946b746a53c4..039c96134470d9f7d66f24a07b7d16ec14694613 100644
--- a/templates/CRM/Dataprocessor/Form/Filter.tpl
+++ b/templates/CRM/Dataprocessor/Form/Filter.tpl
@@ -1,7 +1,4 @@
 {crmScope extensionKey='dataprocessor'}
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="top"}
-</div>
 
 {if $action eq 8}
     {* Are you sure to delete form *}
@@ -9,11 +6,19 @@
     <div class="crm-block crm-form-block crm-data-processor_label-block">
         <div class="crm-section">{ts 1=$filter->title}Are you sure to delete filter '%1'?{/ts}</div>
     </div>
-{else}
+
+    <div class="crm-submit-buttons">
+        {include file="CRM/common/formButtons.tpl" location="bottom"}
+    </div>
+{elseif (!$snippet)}
+
+    <div class="crm-submit-buttons">
+        {include file="CRM/common/formButtons.tpl" location="top"}
+    </div>
 
     {* block for rule data *}
     <h3>{ts}Field{/ts}</h3>
-    <div class="crm-block crm-form-block crm-data-processor_source-block">
+    <div class="crm-block crm-form-block crm-data-processor_filter-block">
         <div class="crm-section">
             <div class="label">{$form.type.label}</div>
             <div class="content">{$form.type.html}</div>
@@ -21,10 +26,19 @@
         </div>
         <div class="crm-section">
             <div class="label">{$form.title.label}</div>
-            <div class="content">{$form.title.html}</div>
+            <div class="content">
+                {$form.title.html}
+                <span class="">
+                {ts}System name:{/ts}&nbsp;
+                <span id="systemName" style="font-style: italic;">{if ($filter)}{$filter.name}{/if}</span>
+                <a href="javascript:void(0);" onclick="jQuery('#nameSection').removeClass('hiddenElement'); jQuery(this).parent().addClass('hiddenElement'); return false;">
+                  {ts}Change{/ts}
+                </a>
+                </span>
+            </div>
             <div class="clear"></div>
         </div>
-        <div class="crm-section">
+        <div id="nameSection" class="crm-section hiddenElement">
             <div class="label">{$form.name.label}</div>
             <div class="content">{$form.name.html}</div>
             <div class="clear"></div>
@@ -34,10 +48,55 @@
             <div class="content">{$form.is_required.html}</div>
             <div class="clear"></div>
         </div>
+
+        <div id="type_configuration">
+            {if ($configuration_template)}
+                {include file=$configuration_template}
+            {/if}
+        </div>
     </div>
-{/if}
 
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="bottom"}
-</div>
+    <script type="text/javascript">
+        {literal}
+        CRM.$(function($) {
+          var id = {/literal}{if ($filter)}{$filter.id}{else}false{/if}{literal};
+          var data_processor_id = {/literal}{$data_processor_id}{literal};
+
+          $('#type').on('change', function() {
+            var type = $('#type').val();
+            if (type) {
+              var dataUrl = CRM.url('civicrm/dataprocessor/form/filter', {type: type, 'data_processor_id': data_processor_id, 'id': id});
+              CRM.loadPage(dataUrl, {'target': '#type_configuration'});
+            }
+          });
+
+          $('#title').on('blur', function() {
+            var title = $('#title').val();
+            if ($('#nameSection').hasClass('hiddenElement') && !id) {
+              CRM.api3('DataProcessorFilter', 'check_name', {
+                'title': title,
+                'data_processor_id': data_processor_id
+              }).done(function (result) {
+                $('#systemName').html(result.name);
+                $('#name').val(result.name);
+              });
+            }
+          });
+
+          $('#type').change();
+        });
+        {/literal}
+    </script>
+
+    <div class="crm-submit-buttons">
+        {include file="CRM/common/formButtons.tpl" location="bottom"}
+    </div>
+
+{else}
+    <div id="type_configuration">
+        {if ($configuration_template)}
+            {include file=$configuration_template}
+        {/if}
+    </div>
+{/if}
 {/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Filter/Configuration/SimpleSqlFilter.tpl b/templates/CRM/Dataprocessor/Form/Filter/Configuration/SimpleSqlFilter.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..699cd97b3d12abaf39898421ff8f7a18bd052863
--- /dev/null
+++ b/templates/CRM/Dataprocessor/Form/Filter/Configuration/SimpleSqlFilter.tpl
@@ -0,0 +1,7 @@
+{crmScope extensionKey='dataprocessor'}
+<div class="crm-section">
+    <div class="label">{$form.field.label}</div>
+    <div class="content">{$form.field.html}</div>
+    <div class="clear"></div>
+</div>
+{/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Output/UIOutput/DateRange.tpl b/templates/CRM/Dataprocessor/Form/Filter/DateRange.tpl
similarity index 100%
rename from templates/CRM/Dataprocessor/Form/Output/UIOutput/DateRange.tpl
rename to templates/CRM/Dataprocessor/Form/Filter/DateRange.tpl
diff --git a/templates/CRM/Dataprocessor/Form/Filter/SimpleFilter.tpl b/templates/CRM/Dataprocessor/Form/Filter/SimpleFilter.tpl
deleted file mode 100644
index c623039c643226698db29c847952d64b60c1bf7f..0000000000000000000000000000000000000000
--- a/templates/CRM/Dataprocessor/Form/Filter/SimpleFilter.tpl
+++ /dev/null
@@ -1,18 +0,0 @@
-{crmScope extensionKey='dataprocessor'}
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="top"}
-</div>
-
-<h3>{ts}Filter configuration{/ts}</h3>
-<div class="crm-block crm-form-block crm-data-processor_source-block">
-    <div class="crm-section">
-        <div class="label">{$form.field.label}</div>
-        <div class="content">{$form.field.html}</div>
-        <div class="clear"></div>
-    </div>
-</div>
-
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="bottom"}
-</div>
-{/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Filter/SimpleSqlFilter.tpl b/templates/CRM/Dataprocessor/Form/Filter/SimpleSqlFilter.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..84e2445936923c32399eaab313df47ff4f56624d
--- /dev/null
+++ b/templates/CRM/Dataprocessor/Form/Filter/SimpleSqlFilter.tpl
@@ -0,0 +1,20 @@
+{assign var=fieldOp     value=$filterName|cat:"_op"}
+{assign var=filterVal   value=$filterName|cat:"_value"}
+{assign var=filterMin   value=$filterName|cat:"_min"}
+{assign var=filterMax   value=$filterName|cat:"_max"}
+
+{if $filter.type == 'Date' || $filter.type == 'Timestamp'}
+    <tr>
+        <td class="label">{$filter.title}</td>
+        {include file="CRM/Dataprocessor/Form/Filter/DateRange.tpl" fieldName=$filterName from='_from' to='_to'}
+    </tr>
+{elseif $form.$fieldOp.html}
+    <tr>
+        <td class="label">{$filter.title}</td>
+        <td>{$form.$fieldOp.html}</td>
+        <td>
+            <span id="{$filterVal}_cell">{$form.$filterVal.label}&nbsp;{$form.$filterVal.html}</span>
+            <span id="{$filterMin}_max_cell">{$form.$filterMin.label}&nbsp;{$form.$filterMin.html}&nbsp;&nbsp;{$form.$filterMax.label}&nbsp;{$form.$filterMax.html}</span>
+        </td>
+    </tr>
+{/if}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Join/Simple.tpl b/templates/CRM/Dataprocessor/Form/Join/Simple.tpl
deleted file mode 100644
index 8feaf84a4b6a6c51fd360f0d32743fab57ad9998..0000000000000000000000000000000000000000
--- a/templates/CRM/Dataprocessor/Form/Join/Simple.tpl
+++ /dev/null
@@ -1,37 +0,0 @@
-{crmScope extensionKey='dataprocessor'}
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="top"}
-</div>
-
-    {* block for rule data *}
-    <h3>{ts}Data Processor Sources simple join configuration{/ts}</h3>
-    <div class="crm-block crm-form-block crm-data-processor_simple_join-block">
-        <div class="crm-section">
-            <table class="form_layout">
-                <tr>
-                    <td>
-                        {$form.left_field.label}
-                    </td>
-                    <td></td>
-                    <td>
-                        {$form.right_field.label}
-                    </td>
-                </tr>
-                <tr>
-                    <td>
-                        {$form.left_field.html}
-                    </td>
-                    <td>=</td>
-                    <td>
-                        {$form.right_field.html}
-                    </td>
-                </tr>
-            </table>
-
-        </div>
-    </div>
-
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="bottom"}
-</div>
-{/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/MultipleDataFlows/SimpleJoin.tpl b/templates/CRM/Dataprocessor/Form/MultipleDataFlows/SimpleJoin.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..5a5f34da0da8da4fa018cf1028cffcb8c87e2064
--- /dev/null
+++ b/templates/CRM/Dataprocessor/Form/MultipleDataFlows/SimpleJoin.tpl
@@ -0,0 +1,10 @@
+{crmScope extensionKey='dataprocessor'}
+<div class="crm-section">
+    <div class="label">{ts}Join on field{/ts} <span class="marker">*</span></div>
+    <div class="content">
+                    {$form.left_field.html}
+                    &nbsp;=&nbsp;
+                    {$form.right_field.html}
+    </div>
+</div>
+{/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Output.tpl b/templates/CRM/Dataprocessor/Form/Output.tpl
index 46ef08e8bd94072146d42ec0a02ed5943ad804b4..f0628bc93d11a4c0aeff8571d5123ec43d879360 100644
--- a/templates/CRM/Dataprocessor/Form/Output.tpl
+++ b/templates/CRM/Dataprocessor/Form/Output.tpl
@@ -1,7 +1,4 @@
 {crmScope extensionKey='dataprocessor'}
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="top"}
-</div>
 
 {if $action eq 8}
     {* Are you sure to delete form *}
@@ -9,20 +6,56 @@
     <div class="crm-block crm-form-block crm-data-processor_label-block">
         <div class="crm-section">{ts}Are you sure to delete data processor output?{/ts}</div>
     </div>
-{else}
+
+    <div class="crm-submit-buttons">
+        {include file="CRM/common/formButtons.tpl" location="bottom"}
+    </div>
+{elseif (!$snippet)}
 
     {* block for rule data *}
-    <h3>{ts}Data Processor Source{/ts}</h3>
+    <h3>{ts}Data Processor Output{/ts}</h3>
     <div class="crm-block crm-form-block crm-data-processor_output-block">
         <div class="crm-section">
             <div class="label">{$form.type.label}</div>
             <div class="content">{$form.type.html}</div>
             <div class="clear"></div>
         </div>
+
+    <div id="type_configuration">
+        {if ($configuration_template)}
+            {include file=$configuration_template}
+        {/if}
+    </div>
+
     </div>
-{/if}
 
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="bottom"}
-</div>
+    <div class="crm-submit-buttons">
+        {include file="CRM/common/formButtons.tpl" location="bottom"}
+    </div>
+
+    <script type="text/javascript">
+        {literal}
+        CRM.$(function($) {
+          var id = {/literal}{if ($output)}{$output.id}{else}false{/if}{literal};
+          var data_processor_id = {/literal}{$data_processor_id}{literal};
+
+          $('#type').on('change', function() {
+            var type = $('#type').val();
+            if (type) {
+              var dataUrl = CRM.url('civicrm/dataprocessor/form/output', {type: type, 'data_processor_id': data_processor_id, 'id': id});
+              CRM.loadPage(dataUrl, {'target': '#type_configuration'});
+            }
+          });
+
+          $('#type').change();
+        });
+        {/literal}
+    </script>
+{else}
+    <div id="type_configuration">
+        {if ($configuration_template)}
+            {include file=$configuration_template}
+        {/if}
+    </div>
+{/if}
 {/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Output/API.tpl b/templates/CRM/Dataprocessor/Form/Output/API.tpl
index b2f118130b5271d99077c7dd5893a9a2f1a44cc6..ad3520dfad3a50914a9d11aeeff4187eca7c0557 100644
--- a/templates/CRM/Dataprocessor/Form/Output/API.tpl
+++ b/templates/CRM/Dataprocessor/Form/Output/API.tpl
@@ -1,33 +1,24 @@
 {crmScope extensionKey='dataprocessor'}
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="top"}
-    </div>
 
-    <h3>{ts}Output configuration{/ts}</h3>
-    <div class="crm-block crm-form-block crm-data-processor_output-block">
-        <div class="crm-section">
-            <div class="label">{$form.api_entity.label}</div>
-            <div class="content">{$form.api_entity.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.api_action.label}</div>
-            <div class="content">{$form.api_action.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.api_count_action.label}</div>
-            <div class="content">{$form.api_count_action.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.permission.label}</div>
-            <div class="content">{$form.permission.html}</div>
-            <div class="clear"></div>
-        </div>
+    <div class="crm-section">
+        <div class="label">{$form.api_entity.label}</div>
+        <div class="content">{$form.api_entity.html}</div>
+        <div class="clear"></div>
     </div>
-
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="bottom"}
+    <div class="crm-section">
+        <div class="label">{$form.api_action.label}</div>
+        <div class="content">{$form.api_action.html}</div>
+        <div class="clear"></div>
+    </div>
+    <div class="crm-section">
+        <div class="label">{$form.api_count_action.label}</div>
+        <div class="content">{$form.api_count_action.html}</div>
+        <div class="clear"></div>
     </div>
+    <div class="crm-section">
+        <div class="label">{$form.permission.label}</div>
+        <div class="content">{$form.permission.html}</div>
+        <div class="clear"></div>
+    </div>
+
 {/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Output/UIOutput/CriteriaForm.tpl b/templates/CRM/Dataprocessor/Form/Output/UIOutput/CriteriaForm.tpl
index 3330dd10d4dc564bd053bca698246e580ad474ad..dffdc70f64bcd3635b4d9c13943fac23aa0555be 100644
--- a/templates/CRM/Dataprocessor/Form/Output/UIOutput/CriteriaForm.tpl
+++ b/templates/CRM/Dataprocessor/Form/Output/UIOutput/CriteriaForm.tpl
@@ -13,25 +13,7 @@
                         <th>{ts}Value{/ts}</th>
                     </tr>
                     {foreach from=$filters key=filterName item=filter}
-                        {assign var=fieldOp     value=$filterName|cat:"_op"}
-                        {assign var=filterVal   value=$filterName|cat:"_value"}
-                        {assign var=filterMin   value=$filterName|cat:"_min"}
-                        {assign var=filterMax   value=$filterName|cat:"_max"}
-                        {if $filter.type == 'Date'}
-                            <tr>
-                                <td class="label">{$filter.title}</td>
-                                {include file="CRM/Dataprocessor/Form/Output/UIOutput/DateRange.tpl" fieldName=$filterName from='_from' to='_to'}
-                            </tr>
-                        {elseif $form.$fieldOp.html}
-                            <tr>
-                                <td class="label">{$filter.title}</td>
-                                <td>{$form.$fieldOp.html}</td>
-                                <td>
-                                    <span id="{$filterVal}_cell">{$form.$filterVal.label}&nbsp;{$form.$filterVal.html}</span>
-                                    <span id="{$filterMin}_max_cell">{$form.$filterMin.label}&nbsp;{$form.$filterMin.html}&nbsp;&nbsp;{$form.$filterMax.label}&nbsp;{$form.$filterMax.html}</span>
-                                </td>
-                            </tr>
-                        {/if}
+                        {include file=$filter.template filterName=$filterName filter=$filter.filter}
                     {/foreach}
                 </table>
                 <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="botton"}</div>
diff --git a/templates/CRM/Dataprocessor/Form/Source.tpl b/templates/CRM/Dataprocessor/Form/Source.tpl
index 449882d1f3dc653167e9a0de27efee415ed04ef1..b0cb470301a32cb12ecde074e1c1500c2ed840ca 100644
--- a/templates/CRM/Dataprocessor/Form/Source.tpl
+++ b/templates/CRM/Dataprocessor/Form/Source.tpl
@@ -1,7 +1,4 @@
 {crmScope extensionKey='dataprocessor'}
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="top"}
-</div>
 
 {if $action eq 8}
     {* Are you sure to delete form *}
@@ -9,7 +6,11 @@
     <div class="crm-block crm-form-block crm-data-processor_label-block">
         <div class="crm-section">{ts 1=$source->title}Are you sure to delete data processor source '%1'?{/ts}</div>
     </div>
-{else}
+
+    <div class="crm-submit-buttons">
+        {include file="CRM/common/formButtons.tpl" location="bottom"}
+    </div>
+{elseif (!$snippet)}
 
     {* block for rule data *}
     <h3>{ts}Data Processor Source{/ts}</h3>
@@ -21,25 +22,82 @@
         </div>
         <div class="crm-section">
             <div class="label">{$form.title.label}</div>
-            <div class="content">{$form.title.html}</div>
+            <div class="content">
+                {$form.title.html}
+                <span class="">
+                {ts}System name:{/ts}&nbsp;
+                <span id="systemName" style="font-style: italic;">{if ($source)}{$source.name}{/if}</span>
+                <a href="javascript:void(0);" onclick="jQuery('#nameSection').removeClass('hiddenElement'); jQuery(this).parent().addClass('hiddenElement'); return false;">
+                  {ts}Change{/ts}
+                </a>
+                </span>
+            </div>
             <div class="clear"></div>
         </div>
-        <div class="crm-section">
+        <div id="nameSection" class="crm-section hiddenElement">
             <div class="label">{$form.name.label}</div>
             <div class="content">{$form.name.html}</div>
             <div class="clear"></div>
         </div>
-        {if !$is_first_data_source}
-            <div class="crm-section">
-                <div class="label">{$form.join_type.label}</div>
-                <div class="content">{$form.join_type.html}</div>
-                <div class="clear"></div>
-            </div>
+
+        <div id="type_configuration">
+            {if ($configuration_template)}
+                {include file=$configuration_template}
+            {/if}
+
+            {include file="CRM/Dataprocessor/Form/Source/Join.tpl"}
+        </div>
+    </div>
+
+    <div class="crm-submit-buttons">
+        {include file="CRM/common/formButtons.tpl" location="bottom"}
+    </div>
+
+    <script type="text/javascript">
+        {literal}
+
+        CRM.$(function($) {
+          $('#type').on('change', function() {
+            var type = $('#type').val();
+            var join_type = $('#join_type').val();
+            var id = {/literal}{if ($source)}{$source.id}{else}false{/if}{literal};
+            var data_processor_id = {/literal}{$data_processor_id}{literal};
+            if (type) {
+              var dataUrl = CRM.url('civicrm/dataprocessor/form/source', {type: type, 'data_processor_id': data_processor_id, 'id': id, 'join_type': join_type});
+              CRM.loadPage(dataUrl, {'target': '#type_configuration'});
+            }
+          });
+
+          $('#title').on('blur', function() {
+            var title = $('#title').val();
+            var id = {/literal}{if ($source)}{$source.id}{else}false{/if}{literal};
+            var data_processor_id = {/literal}{$data_processor_id}{literal};
+            if ($('#nameSection').hasClass('hiddenElement') && !id) {
+              CRM.api3('DataProcessorSource', 'check_name', {
+                'title': title,
+                'data_processor_id': data_processor_id
+              }).done(function (result) {
+                $('#systemName').html(result.name);
+                $('#name').val(result.name);
+              });
+            }
+          });
+
+          $('#type').change();
+        });
+        {/literal}
+    </script>
+
+{elseif ($block == 'joinOnly')}
+    {include file="CRM/Dataprocessor/Form/Source/Join.tpl"}
+{elseif ($block == 'configuration')}
+    <div id="type_configuration">
+        {if ($configuration_template)}
+            {include file=$configuration_template}
         {/if}
+
+        {include file="CRM/Dataprocessor/Form/Source/Join.tpl"}
     </div>
 {/if}
 
-<div class="crm-submit-buttons">
-    {include file="CRM/common/formButtons.tpl" location="bottom"}
-</div>
 {/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Source/Configuration.tpl b/templates/CRM/Dataprocessor/Form/Source/Configuration.tpl
index b0a04cc2668645737e437159ba336039c167ac15..ee554372ed91f671e68235c89eed0f3ca0f60ece 100644
--- a/templates/CRM/Dataprocessor/Form/Source/Configuration.tpl
+++ b/templates/CRM/Dataprocessor/Form/Source/Configuration.tpl
@@ -1,20 +1,16 @@
 {crmScope extensionKey='dataprocessor'}
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="top"}
-    </div>
 
-    {* block for rule data *}
-    <h3>{ts}Data Processor Sources configuration{/ts}</h3>
-    <div class="crm-block crm-form-block crm-data-processor_source_configuration-block">
-        <div class="crm-section">
+{if (count($filter_required_fields))}
+    <div class="crm-accordion-wrapper">
+        <div class="crm-accordion-header">{ts}Filter criteria{/ts}</div>
+        <div class="crm-accordion-body">
 
-            <h3>{ts}Filter criteria{/ts}</h3>
             <table class="report-layout">
-                {foreach from=$filter_fields item=fieldLabel key=fieldName}
+                {foreach from=$filter_required_fields item=fieldLabel key=fieldName}
                     {assign var=fieldOp     value=$fieldName|cat:"_op"}
                     {assign var=fieldVal   value=$fieldName|cat:"_value"}
                     <tr class="report-contents crm-report crm-report-criteria-filter">
-                        <td class="report-contents">{$fieldLabel}</td>
+                        <td class="report-contents">{$fieldLabel} <span class="marker">*</span></td>
                         <td class="report-contents">{$form.$fieldOp.html}</td>
                         <td>{$form.$fieldVal.html}</td>
                     </tr>
@@ -23,8 +19,25 @@
 
         </div>
     </div>
+{/if}
+{if (count($filter_fields))}
+    <div class="crm-accordion-wrapper collapsed">
+        <div class="crm-accordion-header">{ts}Additional filter criteria{/ts}</div>
+        <div class="crm-accordion-body">
+
+            <table class="report-layout">
+                {foreach from=$filter_fields item=fieldLabel key=fieldName}
+                    {assign var=fieldOp     value=$fieldName|cat:"_op"}
+                    {assign var=fieldVal   value=$fieldName|cat:"_value"}
+                    <tr class="report-contents crm-report crm-report-criteria-filter">
+                        <td class="report-contents">{$fieldLabel}</td>
+                        <td class="report-contents">{$form.$fieldOp.html}</td>
+                        <td>{$form.$fieldVal.html}</td>
+                    </tr>
+                {/foreach}
+            </table>
 
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="bottom"}
+        </div>
     </div>
+{/if}
 {/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Source/Csv.tpl b/templates/CRM/Dataprocessor/Form/Source/Csv.tpl
index 57dd837f438394643ab144dd672110d981fbd49f..75d22563545648ccd0650bac5118c2205b5c83c9 100644
--- a/templates/CRM/Dataprocessor/Form/Source/Csv.tpl
+++ b/templates/CRM/Dataprocessor/Form/Source/Csv.tpl
@@ -1,11 +1,8 @@
 {crmScope extensionKey='dataprocessor'}
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="top"}
-    </div>
+<div class="crm-accordion-wrapper">
+    <div class="crm-accordion-header">{ts}Configuration{/ts}</div>
+    <div class="crm-accordion-body">
 
-    {* block for rule data *}
-    <h3>{ts}Data Processor Sources configuration{/ts}</h3>
-    <div class="crm-block crm-form-block crm-data-processor_source_configuration-block">
         <div class="help-block" id="help">
             {ts}<p>On this form you can configure the CSV data source.</p>
                 <p>The <strong>URI</strong> is the file location. Which is either a path on the server  or a URL from where the file could be downloaded.</p>
@@ -41,8 +38,5 @@
             <div class="clear"></div>
         </div>
     </div>
-
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="bottom"}
-    </div>
+</div>
 {/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Source/Join.tpl b/templates/CRM/Dataprocessor/Form/Source/Join.tpl
new file mode 100644
index 0000000000000000000000000000000000000000..5d9f79f606b338c5e3f05b3705a9a9fac813902c
--- /dev/null
+++ b/templates/CRM/Dataprocessor/Form/Source/Join.tpl
@@ -0,0 +1,36 @@
+{crmScope extensionKey='dataprocessor'}
+<div id="joinBlock">
+{if !$is_first_data_source}
+    <div class="crm-accordion-wrapper">
+        <div class="crm-accordion-header">{ts}Join with other sources{/ts}</div>
+        <div class="crm-accordion-body">
+            <div class="crm-section">
+                <div class="label">{$form.join_type.label}</div>
+                <div class="content">{$form.join_type.html}</div>
+                <div class="clear"></div>
+            </div>
+            {if ($join_configuration_template)}
+                {include file=$join_configuration_template}
+            {/if}
+        </div>
+    </div>
+
+    <script type="text/javascript">
+        {literal}
+        CRM.$(function($) {
+          $('#join_type').on('change', function() {
+            var type = $('#type').val();
+            var join_type = $('#join_type').val();
+            var id = {/literal}{if ($source)}{$source.id}{else}false{/if}{literal};
+            var data_processor_id = {/literal}{$data_processor_id}{literal};
+            if (type) {
+              var dataUrl = CRM.url('civicrm/dataprocessor/form/source', {type: type, 'data_processor_id': data_processor_id, 'id': id, 'join_type': join_type, 'block': 'joinOnly'});
+              CRM.loadPage(dataUrl, {'target': '#joinBlock'});
+            }
+          });
+        });
+        {/literal}
+    </script>
+{/if}
+</div>
+{/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/Dataprocessor/Form/Source/Relationship.tpl b/templates/CRM/Dataprocessor/Form/Source/Relationship.tpl
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.tpl b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.tpl
index adf7c385facbc593d1f4208c71b64ab2cd9b4cef..9f0bbbbb4b619be31a8d3eb8a696778c52416e3b 100644
--- a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.tpl
+++ b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ActivitySearch.tpl
@@ -1,43 +1,32 @@
 {crmScope extensionKey='dataprocessor'}
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="top"}
+    <div class="crm-section">
+        <div class="label">{$form.title.label}</div>
+        <div class="content">{$form.title.html}</div>
+        <div class="clear"></div>
     </div>
-
-    <h3>{ts}Output configuration{/ts}</h3>
-    <div class="crm-block crm-form-block crm-data-processor_output-block">
-        <div class="crm-section">
-            <div class="label">{$form.title.label}</div>
-            <div class="content">{$form.title.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.navigation_parent_path.label}</div>
-            <div class="content">{$form.navigation_parent_path.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.permission.label}</div>
-            <div class="content">{$form.permission.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.activity_id_field.label}</div>
-            <div class="content">{$form.activity_id_field.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.hide_id_field.label}</div>
-            <div class="content">{$form.hide_id_field.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.help_text.label}</div>
-            <div class="content">{$form.help_text.html}</div>
-            <div class="clear"></div>
-        </div>
+    <div class="crm-section">
+        <div class="label">{$form.navigation_parent_path.label}</div>
+        <div class="content">{$form.navigation_parent_path.html}</div>
+        <div class="clear"></div>
     </div>
-
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="bottom"}
+    <div class="crm-section">
+        <div class="label">{$form.permission.label}</div>
+        <div class="content">{$form.permission.html}</div>
+        <div class="clear"></div>
+    </div>
+    <div class="crm-section">
+        <div class="label">{$form.activity_id_field.label}</div>
+        <div class="content">{$form.activity_id_field.html}</div>
+        <div class="clear"></div>
+    </div>
+    <div class="crm-section">
+        <div class="label">{$form.hide_id_field.label}</div>
+        <div class="content">{$form.hide_id_field.html}</div>
+        <div class="clear"></div>
+    </div>
+    <div class="crm-section">
+        <div class="label">{$form.help_text.label}</div>
+        <div class="content">{$form.help_text.html}</div>
+        <div class="clear"></div>
     </div>
 {/crmScope}
\ No newline at end of file
diff --git a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ContactSearch.tpl b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ContactSearch.tpl
index 91f8eecec2cdf3503a15e4b8fb268657860ffd0b..4a606293ef2e0aafff2b40c1c695a0cfa0f52665 100644
--- a/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ContactSearch.tpl
+++ b/templates/CRM/DataprocessorSearch/Form/OutputConfiguration/ContactSearch.tpl
@@ -1,43 +1,32 @@
 {crmScope extensionKey='dataprocessor'}
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="top"}
+    <div class="crm-section">
+        <div class="label">{$form.title.label}</div>
+        <div class="content">{$form.title.html}</div>
+        <div class="clear"></div>
     </div>
-
-    <h3>{ts}Output configuration{/ts}</h3>
-    <div class="crm-block crm-form-block crm-data-processor_output-block">
-        <div class="crm-section">
-            <div class="label">{$form.title.label}</div>
-            <div class="content">{$form.title.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.navigation_parent_path.label}</div>
-            <div class="content">{$form.navigation_parent_path.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.permission.label}</div>
-            <div class="content">{$form.permission.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.contact_id_field.label}</div>
-            <div class="content">{$form.contact_id_field.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.hide_id_field.label}</div>
-            <div class="content">{$form.hide_id_field.html}</div>
-            <div class="clear"></div>
-        </div>
-        <div class="crm-section">
-            <div class="label">{$form.help_text.label}</div>
-            <div class="content">{$form.help_text.html}</div>
-            <div class="clear"></div>
-        </div>
+    <div class="crm-section">
+        <div class="label">{$form.navigation_parent_path.label}</div>
+        <div class="content">{$form.navigation_parent_path.html}</div>
+        <div class="clear"></div>
     </div>
-
-    <div class="crm-submit-buttons">
-        {include file="CRM/common/formButtons.tpl" location="bottom"}
+    <div class="crm-section">
+        <div class="label">{$form.permission.label}</div>
+        <div class="content">{$form.permission.html}</div>
+        <div class="clear"></div>
+    </div>
+    <div class="crm-section">
+        <div class="label">{$form.contact_id_field.label}</div>
+        <div class="content">{$form.contact_id_field.html}</div>
+        <div class="clear"></div>
+    </div>
+    <div class="crm-section">
+        <div class="label">{$form.hide_id_field.label}</div>
+        <div class="content">{$form.hide_id_field.html}</div>
+        <div class="clear"></div>
+    </div>
+    <div class="crm-section">
+        <div class="label">{$form.help_text.label}</div>
+        <div class="content">{$form.help_text.html}</div>
+        <div class="clear"></div>
     </div>
 {/crmScope}
\ No newline at end of file
diff --git a/xml/Menu/dataprocessor.xml b/xml/Menu/dataprocessor.xml
index 327842c16b5c6f3c14cfc92a941876f1d679ef51..8e58a5205603a4f8a98dd868aca0a53467efc42d 100644
--- a/xml/Menu/dataprocessor.xml
+++ b/xml/Menu/dataprocessor.xml
@@ -42,13 +42,6 @@
     <access_arguments>access CiviCRM</access_arguments>
     <access_arguments>administer CiviCRM</access_arguments>
   </item>
-  <item>
-    <path>civicrm/dataprocessor/form/filter/simplefilter</path>
-    <page_callback>CRM_Dataprocessor_Form_Filter_SimpleFilter</page_callback>
-    <title>DataProcessor</title>
-    <access_arguments>access CiviCRM</access_arguments>
-    <access_arguments>administer CiviCRM</access_arguments>
-  </item>
   <item>
     <path>civicrm/dataprocessor/form/aggregate_field</path>
     <page_callback>CRM_Dataprocessor_Form_AggregateField</page_callback>
@@ -63,48 +56,6 @@
     <access_arguments>access CiviCRM</access_arguments>
     <access_arguments>administer CiviCRM</access_arguments>
   </item>
-  <item>
-    <path>civicrm/dataprocessor/form/joins/simple_join</path>
-    <page_callback>CRM_Dataprocessor_Form_Join_Simple</page_callback>
-    <title>DataProcessor</title>
-    <access_arguments>access CiviCRM</access_arguments>
-    <access_arguments>administer CiviCRM</access_arguments>
-  </item>
-  <item>
-    <path>civicrm/dataprocessor/form/source/configuration</path>
-    <page_callback>CRM_Dataprocessor_Form_Source_Configuration</page_callback>
-    <title>DataProcessor</title>
-    <access_arguments>access CiviCRM</access_arguments>
-    <access_arguments>administer CiviCRM</access_arguments>
-  </item>
-  <item>
-    <path>civicrm/dataprocessor/form/source/csv</path>
-    <page_callback>CRM_Dataprocessor_Form_Source_Csv</page_callback>
-    <title>DataProcessor</title>
-    <access_arguments>access CiviCRM</access_arguments>
-    <access_arguments>administer CiviCRM</access_arguments>
-  </item>
-  <item>
-    <path>civicrm/dataprocessor/form/output/api</path>
-    <page_callback>CRM_Dataprocessor_Form_Output_API</page_callback>
-    <title>DataProcessor</title>
-    <access_arguments>access CiviCRM</access_arguments>
-    <access_arguments>administer CiviCRM</access_arguments>
-  </item>
-  <item>
-    <path>civicrm/dataprocessor/form/output/contact_search</path>
-    <page_callback>CRM_DataprocessorSearch_Form_OutputConfiguration_ContactSearch</page_callback>
-    <title>DataProcessor</title>
-    <access_arguments>access CiviCRM</access_arguments>
-    <access_arguments>administer CiviCRM</access_arguments>
-  </item>
-  <item>
-    <path>civicrm/dataprocessor/form/output/activity_search</path>
-    <page_callback>CRM_DataprocessorSearch_Form_OutputConfiguration_ActivitySearch</page_callback>
-    <title>DataProcessor</title>
-    <access_arguments>access CiviCRM</access_arguments>
-    <access_arguments>administer CiviCRM</access_arguments>
-  </item>
   <item>
     <path>civicrm/dataprocessor/form/output/download</path>
     <title>Browse Uploaded files</title>
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessor.entityType.php b/xml/schema/CRM/Dataprocessor/DataProcessor.entityType.php
new file mode 100644
index 0000000000000000000000000000000000000000..225f3335dc629df90ec6438b340326c0f3933508
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessor.entityType.php
@@ -0,0 +1,11 @@
+<?php
+// This file declares a new entity type. For more details, see "hook_civicrm_entityTypes" at:
+// http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference
+return array (
+  0 => 
+  array (
+    'name' => 'DataProcessor',
+    'class' => 'CRM_Dataprocessor_DAO_DataProcessor',
+    'table' => 'civicrm_data_processor',
+  ),
+);
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessor.xml b/xml/schema/CRM/Dataprocessor/DataProcessor.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ebcc8997a3632ed5b51337cf9bf18c9213aaa244
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessor.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+
+<table>
+  <base>CRM/Dataprocessor</base>
+  <class>DataProcessor</class>
+  <name>civicrm_data_processor</name>
+  <log>false</log>
+
+  <field>
+    <name>id</name>
+    <type>int unsigned</type>
+    <required>true</required>
+    <comment>Unique DataProcessor ID</comment>
+  </field>
+  <primaryKey>
+    <name>id</name>
+    <autoincrement>true</autoincrement>
+  </primaryKey>
+  <field>
+    <name>name</name>
+    <title>Name</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>title</name>
+    <title>Title</title>
+    <type>varchar</type>
+    <required>true</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>type</name>
+    <title>Type</title>
+    <type>varchar</type>
+    <required>true</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>configuration</name>
+    <title>Configuration</title>
+    <type>text</type>
+    <required>false</required>
+    <length>255</length>
+    <serialize>JSON</serialize>
+  </field>
+  <field>
+    <name>aggregation</name>
+    <title>Aggregation Fields</title>
+    <type>text</type>
+    <required>false</required>
+    <length>255</length>
+    <serialize>JSON</serialize>
+  </field>
+  <field>
+    <name>is_active</name>
+    <title>Is active</title>
+    <type>boolean</type>
+    <required>true</required>
+  </field>
+  <field>
+    <name>description</name>
+    <title>Description</title>
+    <type>text</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>storage_type</name>
+    <title>Storage Type</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>storage_configuration</name>
+    <title>Storage Configuration</title>
+    <type>text</type>
+    <required>false</required>
+    <length>255</length>
+    <serialize>JSON</serialize>
+  </field>
+  <field>
+    <name>status</name>
+    <title>Status</title>
+    <type>int unsigned</type>
+    <required>false</required>
+    <default>0</default>
+  </field>
+  <field>
+    <name>source_file</name>
+    <title>Source File</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+
+</table>
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessorField.entityType.php b/xml/schema/CRM/Dataprocessor/DataProcessorField.entityType.php
new file mode 100644
index 0000000000000000000000000000000000000000..70a38a4adfe42f18e8a766130cc8c7f8cc285cf5
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessorField.entityType.php
@@ -0,0 +1,11 @@
+<?php
+// This file declares a new entity type. For more details, see "hook_civicrm_entityTypes" at:
+// http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference
+return array (
+  0 => 
+  array (
+    'name' => 'DataProcessorField',
+    'class' => 'CRM_Dataprocessor_DAO_DataProcessorField',
+    'table' => 'civicrm_data_processor_field',
+  ),
+);
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessorField.xml b/xml/schema/CRM/Dataprocessor/DataProcessorField.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c9a2880f6aa36a4f83bbff0b19bb6bc13939c7b3
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessorField.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+
+<table>
+  <base>CRM/Dataprocessor</base>
+  <class>DataProcessorField</class>
+  <name>civicrm_data_processor_field</name>
+  <log>false</log>
+
+  <field>
+    <name>id</name>
+    <type>int unsigned</type>
+    <required>true</required>
+    <comment>Unique DataProcessorField ID</comment>
+  </field>
+  <primaryKey>
+    <name>id</name>
+    <autoincrement>true</autoincrement>
+  </primaryKey>
+
+  <field>
+    <name>data_processor_id</name>
+    <title>Data Processor ID</title>
+    <type>int unsigned</type>
+    <required>true</required>
+    <comment>FK to Data Processor</comment>
+  </field>
+  <field>
+    <name>weight</name>
+    <title>Weight</title>
+    <type>int</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>name</name>
+    <title>Name</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>title</name>
+    <title>Title</title>
+    <type>varchar</type>
+    <required>true</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>type</name>
+    <title>Type</title>
+    <type>varchar</type>
+    <required>true</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>configuration</name>
+    <title>Configuration</title>
+    <type>text</type>
+    <required>false</required>
+    <length>255</length>
+    <serialize>JSON</serialize>
+  </field>
+  <foreignKey>
+    <name>data_processor_id</name>
+    <table>civicrm_data_processor</table>
+    <key>id</key>
+    <onDelete>CASCADE</onDelete>
+  </foreignKey>
+
+</table>
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessorFilter.entityType.php b/xml/schema/CRM/Dataprocessor/DataProcessorFilter.entityType.php
new file mode 100644
index 0000000000000000000000000000000000000000..b2f41a5efde3e2a201a88507b97c19ab78330bcd
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessorFilter.entityType.php
@@ -0,0 +1,11 @@
+<?php
+// This file declares a new entity type. For more details, see "hook_civicrm_entityTypes" at:
+// http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference
+return array (
+  0 => 
+  array (
+    'name' => 'DataProcessorFilter',
+    'class' => 'CRM_Dataprocessor_DAO_DataProcessorFilter',
+    'table' => 'civicrm_data_processor_filter',
+  ),
+);
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessorFilter.xml b/xml/schema/CRM/Dataprocessor/DataProcessorFilter.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1fed632bc30ab3e2576a1b2c6bcda7ab7e6666a4
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessorFilter.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+
+<table>
+  <base>CRM/Dataprocessor</base>
+  <class>DataProcessorFilter</class>
+  <name>civicrm_data_processor_filter</name>
+  <log>false</log>
+
+  <field>
+    <name>id</name>
+    <type>int unsigned</type>
+    <required>true</required>
+    <comment>Unique DataProcessorFilter ID</comment>
+  </field>
+  <primaryKey>
+    <name>id</name>
+    <autoincrement>true</autoincrement>
+  </primaryKey>
+
+  <field>
+    <name>data_processor_id</name>
+    <title>Data Processor ID</title>
+    <type>int unsigned</type>
+    <required>true</required>
+    <comment>FK to Data Processor</comment>
+  </field>
+  <field>
+    <name>weight</name>
+    <title>Weight</title>
+    <type>int</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>name</name>
+    <title>Name</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>title</name>
+    <title>Title</title>
+    <type>varchar</type>
+    <required>true</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>type</name>
+    <title>Type</title>
+    <type>varchar</type>
+    <required>true</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>is_required</name>
+    <title>Is required</title>
+    <type>boolean</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>configuration</name>
+    <title>Configuration</title>
+    <type>text</type>
+    <required>false</required>
+    <length>255</length>
+    <serialize>JSON</serialize>
+  </field>
+  <foreignKey>
+    <name>data_processor_id</name>
+    <table>civicrm_data_processor</table>
+    <key>id</key>
+    <onDelete>CASCADE</onDelete>
+  </foreignKey>
+
+</table>
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessorOutput.entityType.php b/xml/schema/CRM/Dataprocessor/DataProcessorOutput.entityType.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd70874609fbd407682ac6647e2145e1f79c1dd8
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessorOutput.entityType.php
@@ -0,0 +1,11 @@
+<?php
+// This file declares a new entity type. For more details, see "hook_civicrm_entityTypes" at:
+// http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference
+return array (
+  0 => 
+  array (
+    'name' => 'DataProcessorOutput',
+    'class' => 'CRM_Dataprocessor_DAO_DataProcessorOutput',
+    'table' => 'civicrm_data_processor_output',
+  ),
+);
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessorOutput.xml b/xml/schema/CRM/Dataprocessor/DataProcessorOutput.xml
new file mode 100644
index 0000000000000000000000000000000000000000..38fd881591a056b8dd85232e7b82174ba2972858
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessorOutput.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+
+<table>
+  <base>CRM/Dataprocessor</base>
+  <class>DataProcessorOutput</class>
+  <name>civicrm_data_processor_output</name>
+  <log>false</log>
+
+  <field>
+    <name>id</name>
+    <type>int unsigned</type>
+    <required>true</required>
+    <comment>Unique DataProcessorOutput ID</comment>
+  </field>
+  <primaryKey>
+    <name>id</name>
+    <autoincrement>true</autoincrement>
+  </primaryKey>
+  <field>
+    <name>data_processor_id</name>
+    <title>Data Processor ID</title>
+    <type>int unsigned</type>
+    <required>true</required>
+    <comment>FK to Data Processor</comment>
+  </field>
+  <field>
+    <name>type</name>
+    <title>Type</title>
+    <type>varchar</type>
+    <required>true</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>configuration</name>
+    <title>Configuration</title>
+    <type>text</type>
+    <required>false</required>
+    <length>255</length>
+    <serialize>JSON</serialize>
+  </field>
+
+  <field>
+    <name>permission</name>
+    <title>Permission</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>api_entity</name>
+    <title>API Entity</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>api_action</name>
+    <title>API Action</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>api_count_action</name>
+    <title>API Getcount action</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+
+  <foreignKey>
+    <name>data_processor_id</name>
+    <table>civicrm_data_processor</table>
+    <key>id</key>
+    <onDelete>CASCADE</onDelete>
+  </foreignKey>
+
+</table>
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessorSource.entityType.php b/xml/schema/CRM/Dataprocessor/DataProcessorSource.entityType.php
new file mode 100644
index 0000000000000000000000000000000000000000..0f73c2aef4c50f6b6779b5158c3c1b1a8149ad35
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessorSource.entityType.php
@@ -0,0 +1,11 @@
+<?php
+// This file declares a new entity type. For more details, see "hook_civicrm_entityTypes" at:
+// http://wiki.civicrm.org/confluence/display/CRMDOC/Hook+Reference
+return array (
+  0 => 
+  array (
+    'name' => 'DataProcessorSource',
+    'class' => 'CRM_Dataprocessor_DAO_DataProcessorSource',
+    'table' => 'civicrm_data_processor_source',
+  ),
+);
diff --git a/xml/schema/CRM/Dataprocessor/DataProcessorSource.xml b/xml/schema/CRM/Dataprocessor/DataProcessorSource.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fc75614a12fabb67d06883691f48bc3c23fbb9ec
--- /dev/null
+++ b/xml/schema/CRM/Dataprocessor/DataProcessorSource.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="iso-8859-1" ?>
+
+<table>
+  <base>CRM/Dataprocessor</base>
+  <class>DataProcessorSource</class>
+  <name>civicrm_data_processor_source</name>
+  <log>false</log>
+
+  <field>
+    <name>id</name>
+    <type>int unsigned</type>
+    <required>true</required>
+    <comment>Unique DataProcessorSource ID</comment>
+  </field>
+  <primaryKey>
+    <name>id</name>
+    <autoincrement>true</autoincrement>
+  </primaryKey>
+
+  <field>
+    <name>data_processor_id</name>
+    <title>Data Processor ID</title>
+    <type>int unsigned</type>
+    <required>true</required>
+    <comment>FK to Data Processor</comment>
+  </field>
+  <field>
+    <name>weight</name>
+    <title>Weight</title>
+    <type>int</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>name</name>
+    <title>Name</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>title</name>
+    <title>Title</title>
+    <type>varchar</type>
+    <required>true</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>type</name>
+    <title>Type</title>
+    <type>varchar</type>
+    <required>true</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>configuration</name>
+    <title>Configuration</title>
+    <type>text</type>
+    <required>false</required>
+    <length>255</length>
+    <serialize>JSON</serialize>
+  </field>
+  <field>
+    <name>join_type</name>
+    <title>Join Type</title>
+    <type>varchar</type>
+    <required>false</required>
+    <length>255</length>
+  </field>
+  <field>
+    <name>join_configuration</name>
+    <title>Join Configuration</title>
+    <type>text</type>
+    <required>false</required>
+    <length>255</length>
+    <serialize>JSON</serialize>
+  </field>
+  <foreignKey>
+    <name>data_processor_id</name>
+    <table>civicrm_data_processor</table>
+    <key>id</key>
+    <onDelete>CASCADE</onDelete>
+  </foreignKey>
+
+</table>