diff --git a/salsa_entity.drush.inc b/salsa_entity.drush.inc
index 433a38c..f58f253 100644
--- a/salsa_entity.drush.inc
+++ b/salsa_entity.drush.inc
@@ -13,105 +13,229 @@ function salsa_entity_drush_command() {
     'description' => dt('Generates a file with all translatable strings.'),
   );
   $items['salsa-entity-export'] = array(
-    'description' => dt('Export all objects of the given type'),
+    'description' => dt('Export salsa entities of the given types.'),
     'arguments' => array(
-      'type' => dt('The salsa type, e.g. donate_page'),
+      'types' => dt('The salsa types (comma separated), e.g. supporter,donate_page to be exported.'),
+      'directory' => dt('Destination folder where to export the files.'),
+    ),
+    'options' => array(
+      'paging' => dt('Number of records per file (max and default value is 500 records, how much salsa otherwise allows).'),
     )
   );
   $items['salsa-entity-import'] = array(
-    'description' => dt('Import all salsa entities from the provided export'),
+    'description' => dt('Import salsa entities from the provided export.'),
     'arguments' => array(
-      'file' => dt('The file that should be imported.'),
+      'types' => dt('The salsa types (comma separated), e.g. supporter,donate_page to be imported.'),
+      'directory' => dt('Source folder from where to import the files.'),
+    ),
+    'options' => array(
+      'mapping_file' => dt('Location of JSON file in which is stored source <-> target keys pairs.'),
     )
   );
   return $items;
 }
 
 /**
- * Export salsa entities.
+ * Drush callback: Exports salsa entities.
+ *
+ * @param array $types
+ *   The salsa type, e.g. donate_page.
+ *
+ * @param string $directory
+ *   Destination folder where to export the files.
+ *
+ * @return string
+ *   Drush error messages if any, otherwise function provides output as JSON file.
  */
-function drush_salsa_entity_export($type = NULL) {
-  if (!$type) {
-    return drush_set_error(dt('You need to provide a salsa type.'));
+function drush_salsa_entity_export($types, $directory) {
+  // Make sure export directory exists.
+  if ($directory) {
+    try {
+      $directory = new DirectoryIterator($directory);
+      if (!$directory->isWritable()) {
+        return drush_set_error(dt('Directory @directory is not writable. Please check permissions.'));
+      }
+    }
+    catch(UnexpectedValueException $e) {
+      return drush_set_error(dt('The directory you entered could not be opened. Please check the path.'));
+    }
+  }
+  else {
+    return;
   }
 
-  $entities[$type] = array();
-  foreach (entity_load('salsa_' . $type) as $entity) {
-    // Extract all relevant properties, filter out empty ones.
-    $entities[$type][$entity->identifier()] = array_filter(get_object_vars($entity));
+  // Check paging option.
+  $paging = drush_get_option('paging', 500);
+  if ($paging > 500) {
+    return drush_set_error(dt('Number of records per file can not be bigger than 500.'));
   }
 
-  $header = '<?php
-// Exported Salsa entities for ' . $type . "\n\n";
+  // Prepare sub-directories and export objects into .csv files.
+  $salsa_types = salsa_entity_object_types();
+  $types = explode(',', $types);
+  foreach ($types as $type) {
+    // This check is necessary because of manually entered types.
+    if (array_key_exists($type, $salsa_types)) {
+      $subdirectory = $directory->getPath() . '/' . $type;
+      if (!file_prepare_directory($subdirectory)) {
+        return drush_set_error(dt('You need to create and set writable permissions manually for @subdirectory directory.', array('@subdirectory' => $subdirectory)));
+      }
 
-  drush_print($header);
+      // Remove previously exported files if any.
+      $files = scandir($subdirectory);
+      foreach ($files as $file) {
+        if ($file != '.' && $file != '..') {
+          drupal_unlink($subdirectory . '/' . $file);
+        }
+      }
 
-  // Export data.
-  drush_print('$entities = ' . var_export($entities, TRUE) . ';');
-}
+      $offset = 0;
+      $sequence = 0;
+
+      do {
+        if ($entities = salsa_api()->getObjects($type, array(), $offset . ',' . $paging)) {
+          $destination = $subdirectory . '/' . $type . '_' . $sequence . '.json';
+          file_put_contents($destination, json_encode($entities));
 
-function drush_salsa_entity_import($file = NULL) {
-  if (!$file) {
-    return drush_set_error(dt('You need to provide a file to import from.'));
+          $sequence++;
+          $offset = $offset + $paging;
+
+          drush_print(dt('Successfully created @destination file.', array('@destination' => $destination)));
+        }
+        else {
+          break;
+        }
+      } while (TRUE);
+    }
   }
+}
 
-  if (!file_exists($file)) {
-    // Drush changes the current working directory to the drupal root directory.
-    // Also check the current directory.
-    if (!file_exists(drush_cwd() . '/' . $file)) {
-      return drush_set_error(dt('@name does not exists or is not accessible.', array('@name' => $file)));
+/**
+ * Drush callback: Imports salsa entities.
+ *
+ * @param string $types
+ *   The salsa type, e.g. donate_page.
+ *
+ * @param string $directory
+ *   Source folder from where to import the files.
+ *
+ * @return string
+ *   Error messages if any.
+ */
+function drush_salsa_entity_import($types, $directory) {
+  // Make sure import directory exists.
+  if ($directory) {
+    try {
+      $directory = new DirectoryIterator($directory);
+      if (!$directory->isReadable()) {
+        return drush_set_error(dt('Directory @directory is unreadable. Please check permissions.'));
+      }
     }
-    else {
-      // The path is relative to the current directory, update the variable.
-      $file = drush_cwd() . '/' . $file;
+    catch(UnexpectedValueException $e) {
+      return drush_set_error(dt('The directory you entered could not be opened. Please check the path.'));
     }
   }
-
-  include $file;
-  if (empty($entities)) {
-    return drush_set_error(dt('Provided file is not valid'));
+  else {
+    return;
   }
 
-  $mappings = variable_get('salsa_entity_id_mappings', array());
-  $new_mapping_definitions = array();
-
-  foreach ($entities as $type => $entities_type) {
-    drush_log(dt('Starting to process @type.', array('@type' => $type)));
-    foreach ($entities_type as $id => $values) {
-      // Check if this is a new entity.
-      $existing = FALSE;
-      $old_key = NULL;
-      if (isset($mappings[$type][$id])) {
-        drush_log(dt('Entity @id exists already with local mapped id @local_id.', array('@id' => $id, '@local_id' => $mappings[$type][$id])));
-
-        // Replace key with local mapping to update the existing record.
-        $values[$type . '_KEY'] = $mappings[$type][$id];
-        $values['key'] = $mappings[$type][$id];
-        $existing = TRUE;
-      }
-      else {
-        drush_log(dt('Entity @id is new.', array('@id' => $id)));
-        // Save as a new entity.
-        unset($values[$type . '_KEY']);
-        unset($values['key']);
-      }
+  // Scan and collect all files.
+  $types = explode(',', $types);
+  $salsa_types = salsa_entity_object_types();
+  foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory->getPath(), RecursiveDirectoryIterator::KEY_AS_PATHNAME), RecursiveIteratorIterator::CHILD_FIRST) as $file => $info) {
+    $tok = strtok($info->getFilename(), '_');
+    if ($info->isFile() && in_array($tok, $types) && array_key_exists($tok, $salsa_types) && $info->getExtension() == 'json') {
+      $files[] = $file;
+    }
+  };
+
+  // Go through each file and import one by one record.
+  if (!empty($files)) {
+    foreach ($files as $file) {
+      drush_print(dt('Importing file @file', array('@file' => $file)));
+
+      $type = strtok(basename($file), '_');
+      $json = json_decode(file_get_contents($file), TRUE);
+      foreach ($json as $record) {
+        // Check whether the record already imported.
+        if (salsa_sync_map_key($type, $record['key'])) {
+          continue;
+        }
 
-      // Remove the organization_KEY
-      unset($values['organization_KEY']);
+        $source_key = $record['key'];
 
-      $entity = entity_create('salsa_' . $type, $values);
-      $entity->save();
+        $type_key = $type . '_KEY';
+        unset($record[$type_key]);
+        unset($record['key']);
+        unset($record['organization_KEY']);
 
-      drush_log(dt('Saved entity with id @id.', array('@id' => $entity->identifier())), 'success');
+        $entity = entity_create('salsa_' . $type, $record);
+        $entity->save();
 
-      // Add a new mapping line if this is a new object.
-      if (!$existing) {
-        $new_mapping_definitions[] = "\$conf['salsa_entity_id_mappings']['$type'][$id] = " . $entity->identifier() . ';';
+        salsa_sync_map_key($type, $source_key, $entity->key);
+
+        // @todo Implement mapping.
+        // @todo Is it important the order in which objects are imported? If objects getting new KEYs on import, then for example donation import will depends on supporter, we should import supporters first, to store their mapping somewhere in order to connect donation to proper supporter later.
+        // @todo Where to store mapping definitions. Is local.settings.php appropriate solution? Maybe to generate file that will be located in the root of the source folder?
+        // @todo Do better file check, what if we get a file like this one ".~lock.donation_0.csv#" or any others which is not .csv and does not follow TYPE_SEQUENCE.csv pattern.
       }
     }
+
+    // Save or dump mapping.
+    salsa_sync_map_key(NULL, NULL, NULL, TRUE);
+  }
+  else {
+    drush_set_error(dt('No files to import.'));
   }
-  drush_log(dt('Created @count new objects, add the following mapping definitions to local.settings.php', array('@count' => count($new_mapping_definitions))), 'success');
-  drush_print(implode("\n", $new_mapping_definitions));
+}
+
+/**
+ * Helper function: Maps salsa source <-> target keys.
+ *
+ * @param string $table
+ *   The salsa type (table), e.g. donate_page.
+ *
+ * @param string $source_key
+ *   Source KEY, record ID from the old database.
+ *
+ * @param string $target_key
+ *   Target KEY, record ID in the new database.
+ *
+ * @param bool $save
+ *   Flag, indicates whether to preserve the mapping array as a JSON file or not.
+ *
+ * @return array
+ *   Mapping array (source <-> target key pairs).
+ */
+function salsa_sync_map_key($table = NULL, $source_key = NULL, $target_key = NULL, $save = FALSE) {
+  static $mapping = array();
+
+  // Load default values on first call if mapping_file option is specified.
+  // @todo Validate mapping_file, check whether file exists, that is readable and .json file.
+  $mapping_file = drush_get_option('mapping_file', FALSE);
+  if (empty($mapping) && $mapping_file) {
+    $mapping = json_decode(file_get_contents($mapping_file), TRUE);
+  }
+
+  // Save call is triggered.
+  if ($save) {
+    if ($mapping_file && file_put_contents($mapping_file, json_encode($mapping))) {
+      drush_print(dt('Mapping has been successfully preserved in @mapping_file', array('@mapping_file' => $mapping_file)));
+    }
+    else {
+      drush_print_r(json_encode($mapping));
+    }
+
+    return;
+  }
+
+  // 'Read' call.
+  if (is_null($target_key)) {
+    return $mapping[$table][$source_key];
+  }
+
+  // 'Set' call.
+  $mapping[$table][$source_key] = $target_key;
 }
 
 /**
@@ -145,23 +269,23 @@ function drush_salsa_entity_generate_translatables() {
       }
     }
     foreach ($salsa_info[$name]['item'] as $item) {
-     // Skip some internal/technical things.
-     foreach (array('READONLY', 'PRIVATE', 'KEY') as $ignore_pattern) {
-       if (strpos($item['name'], $ignore_pattern) !== FALSE) {
-         continue 2;
-       }
-     }
-     fwrite($file, "t('" . $item['label'] . "');\n");
-
-     // Write out enum values.
-     if ((strpos($item['type'], 'enum') === 0 || strpos($item['type'], 'set') === 0) && !empty($item['values'])) {
-       foreach (explode(',', $item['values']) as $value) {
-         // Ignore empty values, those with underscores and uppercase values.
-         if (!empty($value) && strpos($value, '_') === FALSE && $value != strtoupper($value)) {
-           fwrite($file, "t('" . $value . "');\n");
-         }
-       }
-     }
+      // Skip some internal/technical things.
+      foreach (array('READONLY', 'PRIVATE', 'KEY') as $ignore_pattern) {
+        if (strpos($item['name'], $ignore_pattern) !== FALSE) {
+          continue 2;
+        }
+      }
+      fwrite($file, "t('" . $item['label'] . "');\n");
+
+      // Write out enum values.
+      if ((strpos($item['type'], 'enum') === 0 || strpos($item['type'], 'set') === 0) && !empty($item['values'])) {
+        foreach (explode(',', $item['values']) as $value) {
+          // Ignore empty values, those with underscores and uppercase values.
+          if (!empty($value) && strpos($value, '_') === FALSE && $value != strtoupper($value)) {
+            fwrite($file, "t('" . $value . "');\n");
+          }
+        }
+      }
     }
     fwrite($file, "\n");
   }
