diff --git a/devel_generate/devel_generate.drush.inc b/devel_generate/devel_generate.drush.inc
old mode 100644
new mode 100755
index efc3b25..44aec25
--- a/devel_generate/devel_generate.drush.inc
+++ b/devel_generate/devel_generate.drush.inc
@@ -8,243 +8,44 @@
  * Implementation of hook_drush_command().
  */
 function devel_generate_drush_command() {
-  $items['generate-users'] = array(
-    'callback' => 'drush_devel_generate_users',
-    'description' => 'Create users.',
-    'arguments' => array(
-      'number_users' => 'Number of users to generate.',
-    ),
-    'options' => array(
-      'kill' => 'Delete all users before generating new ones.',
-      'roles' => 'A comma delimited list of role IDs which should be granted to the new users. No need to specify authenticated user role.',
-      'pass' => 'Specify a password to be set for all generated users.',
-    ),
-    'aliases' => array('genu'),
-  );
-  $items['generate-terms'] = array(
-    'callback' => 'drush_devel_generate_terms',
-    'description' => 'Create terms in specified vocabulary.',
-    'arguments' => array(
-      'machine_name' => 'Vocabulary machine name into which new terms will be inserted.',
-      'number_terms' => 'Number of terms to insert. Defaults to 10.',
-    ),
-    'options' => array(
-      'kill' => 'Delete all terms in specified vocabulary before generating.',
-      'feedback' => 'An integer representing interval for insertion rate logging. Defaults to 1000',
-      'pipe' => 'Returns the list of generated terms, one per line.',
-    ),
-    'aliases' => array('gent'),
 
-  );
-  $items['generate-vocabs'] = array(
-    'callback' => 'drush_devel_generate_vocabs',
-    'description' => 'Create vocabularies.',
-    'arguments' => array(
-      'num_vocabs' => 'Number of vocabularies to create. Defaults to 1.',
-    ),
-    'options' => array(
-      'kill' => 'Delete all vocabularies before generating.',
-      'pipe' => 'Returns the list of generated vocabularies, one per line.',
-    ),
-    'aliases' => array('genv'),
-  );
-  $items['generate-content'] = array(
-    'callback' => 'drush_devel_generate_content',
-    'description' => 'Create content.',
-    'drupal dependencies' => array('devel_generate'),
-    'arguments' => array(
-      'number_nodes' => 'Number of nodes to generate.',
-      'maximum_comments' => 'Maximum number of comments to generate.',
-    ),
-    'options' => array(
-      'kill' => 'Delete all content before generating new content.',
-      'types' => 'A comma delimited list of content types to create. Defaults to page,article.',
-      'feedback' => 'An integer representing interval for insertion rate logging. Defaults to 1000',
-      'skip-fields' => 'A comma delimited list of fields to omit when generating random values',
-      'languages' => 'A comma-separated list of language codes',
-    ),
-    'aliases' => array('genc'),
-  );
-  $items['generate-menus'] = array(
-    'callback' => 'drush_devel_generate_menus',
-    'description' => 'Create menus and menu items.',
-    'drupal dependencies' => array('devel_generate'), // Remove these once devel.module is moved down a directory. http://drupal.org/node/925246
-    'arguments' => array(
-      'number_menus' => 'Number of menus to generate. Defaults to 2.',
-      'number_links' => 'Number of links to generate. Defaults to 50.',
-      'max_depth' => 'Max link depth. Defaults to 3',
-      'max_width' => 'Max width of first level of links. Defaults to 8.',
-    ),
-    'options' => array(
-      'kill' => 'Delete all previously generated menus and links before generating new menus and links.',
-      'pipe' => 'Returns the list of generated menus, one per line.',
-    ),
-    'aliases' => array('genm'),
-  );
-  return $items;
-}
-
-
-/**
- * Command callback. Generate a number of users.
- */
-function drush_devel_generate_users($num_users = NULL) {
-  if (drush_generate_is_number($num_users) == FALSE) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', t('Invalid number of users.'));
-  }
-  drush_generate_include_devel();
-  $roles = drush_get_option('roles') ? explode(',', drush_get_option('roles')) : array();
-  $pass = drush_get_option('pass', NULL);
-  devel_create_users($num_users, drush_get_option('kill'), 0, $roles, $pass);
-  drush_log(t('Generated @number users.', array('@number' => $num_users)), 'success');
-}
-
-/**
- * Command callback. Generate a number of terms in given vocabs.
- */
-function drush_devel_generate_terms($vname = NULL, $num_terms = 10) {
-  // Try to convert machine name to a vocab ID
-  if (!$vocab = entity_load('taxonomy_vocabulary', $vname)) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid vocabulary name: !name', array('!name' => $vname)));
-  }
-  if (drush_generate_is_number($num_terms) == FALSE) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid number of terms: !num', array('!num' => $num_terms)));
-  }
-
-  drush_generate_include_devel();
-  if (drush_get_option('kill')) {
-    devel_generate_delete_vocabulary_terms($vocab->vid);
-    drush_log(dt('Deleted existing terms.'), 'success');
-  }
-  $new_terms = devel_generate_terms($num_terms, array($vocab->vid => $vocab), '12');
-  if (!empty($new_terms)) {
-    drush_log(dt("Created the following new terms:\n!terms", array('!terms' => implode("\n", $new_terms))), 'success');
-    drush_print_pipe($new_terms);
-  }
-}
-
-/**
- * Command callback. Generate a number of vocabularies.
- */
-function drush_devel_generate_vocabs($num_vocab = 1) {
-  if (drush_generate_is_number($num_vocab) == FALSE) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid number of vocabularies: !num.', array('!num' => $num_vocab)));
-  }
-  drush_generate_include_devel();
-  if (drush_get_option('kill')) {
-    devel_generate_delete_vocabularies();
-    drush_log(dt('Deleted existing vocabularies.'), 'success');
-  }
-  $new_vocs = devel_generate_vocabs($num_vocab, '12');
-  if (!empty($new_vocs)) {
-    drush_log(dt("Created the following new vocabularies:\n!vocs", array('!vocs' => implode("\n", $new_vocs))), 'success');
-    drush_print_pipe($new_vocs);
-  }
-}
-
-/**
- * Command callback. Generate a number of nodes and comments.
- */
-function drush_devel_generate_content($num_nodes = NULL, $max_comments = NULL) {
-  if (drush_generate_is_number($num_nodes) == FALSE) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid number of nodes'));
-  }
-  if (!empty($max_comments) && drush_generate_is_number($max_comments) == FALSE) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid number of comments.'));
-  }
+  $devel_generate_manager = \Drupal::service('plugin.manager.develgenerate');
+  $definitions = \Drupal::service('plugin.manager.develgenerate')->getDefinitions();
 
-  $add_language = drush_get_option('languages');
-  if (!empty($add_language)) {
-    $add_language = explode(',', str_replace(' ', '', $add_language));
-    // Intersect with the enabled languages to make sure the language args
-    // passed are actually enabled.
-    $values['values']['add_language'] = array_intersect($add_language, array_keys(locale_language_list()));
+  foreach ($definitions as $id => $plugin_info) {
+    $command_suffix = $plugin_info['drushSettings']['suffix'];
+    $alias = $plugin_info['drushSettings']['alias'];
+    $items["generate-$command_suffix"] = array(
+      'callback' => 'drush_devel_generate',
+      'description' => "Create $id.",
+      'callback arguments' => array(
+        'plugin_id' => $id,
+      ),
+      'aliases' => array("gen$alias"),
+    );
+    $items["generate-$command_suffix"]['options'] = $plugin_info['drushSettings'];
+    $items["generate-$command_suffix"]['arguments'] = $plugin_info['drushArgs'];
   }
 
-  // Load user 1; is needed for creating *published* comments.
-  // This code breaks D8 and is not needed there. Perhaps unneeded on D7 as well.
-  if ($max_comments && drush_drupal_major_version() <= 7) {
-    global $user;
-    $user_one = user_load(1);
-    $user = $user_one;
-    drupal_save_session(FALSE);
-  }
-
-  $values['values']['kill_content'] = drush_get_option('kill');
-  $values['values']['title_length'] = 6;
-  $values['values']['num_nodes'] = $num_nodes;
-  $values['values']['max_comments'] = $max_comments;
-  $all_types = array_keys(node_type_get_names());
-  $default_types = array_intersect(array('page', 'article'), $all_types);
-  $selected_types = _convert_csv_to_array(drush_get_option('types', $default_types));
-  if (empty($selected_types)) {
-    return drush_set_error('DEVEL_GENERATE_NO_CONTENT_TYPES', dt('No content types available'));
-  }
-  $values['values']['node_types'] = drupal_map_assoc($selected_types);
-  $node_types = array_filter($values['values']['node_types']);
-  if (!empty($values['values']['kill_content']) && empty($node_types)) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Please provide content type (--types) in which you want to delete the content.'));
-  }
-  drush_generate_include_devel();
-  devel_generate_content($values);
-  drush_log(t('Generated @num_nodes nodes, @max_comments comments (or less) per node.', array('@num_nodes' => (int)$num_nodes, '@max_comments' => (int)$max_comments)), 'success');
+  return $items;
 }
 
 /**
- * Command callback. Generate a number of menus and menu links.
+ * Command callback.
  */
-function drush_devel_generate_menus($number_menus = 2, $number_links = 50, $max_depth = 3, $max_width = 8) {
-  if (drush_generate_is_number($number_menus) == FALSE) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid number of menus'));
-  }
-  if (drush_generate_is_number($number_links) == FALSE) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid number of links'));
-  }
-  if (drush_generate_is_number($max_depth) == FALSE || $max_depth > 9 || $max_depth < 1) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid maximum link depth. Use a value between 1 and 9'));
-  }
-  if (drush_generate_is_number($max_width) == FALSE || $max_width < 1) {
-    return drush_set_error('DEVEL_GENERATE_INVALID_INPUT', dt('Invalid maximum menu width. Use a positive numeric value.'));
-  }
+function drush_devel_generate() {
 
-  global $user;
-  $user_one = user_load(1);
-  $user = $user_one;
-  drupal_save_session(FALSE);
+  //Array of "Callback arguments" and "command line args".
+  $params = func_get_args();
 
-  drush_generate_include_devel();
+  //Getting plugin_id and leaving the command line args
+  $plugin_id = array_shift($params);
 
-  // Delete custom menus.
-  if (drush_get_option('kill')) {
-    devel_generate_delete_menus();
-    drush_log(dt('Deleted existing menus and links.'), 'success');
-  }
-
-  // Generate new menus.
-  $new_menus = devel_generate_menus($number_menus, '12');
-  if (!empty($new_menus)) {
-    drush_log(dt("Created the following new menus:\n!menus", array('!menus' => implode("\n", $new_menus))), 'success');
-    drush_print_pipe($new_menus);
-  }
-
-  // Generate new menu links.
-  $link_types = drupal_map_assoc(array('node', 'front', 'external'));
-  $new_links = devel_generate_links($number_links, $new_menus, '12', $link_types, $max_depth, $max_width);
-  drush_log(dt('Created !count new menu links.', array('!count' => count($new_links))), 'success');
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// Helper functions
-
-// Verify if param is a number.
-function drush_generate_is_number($number) {
-  if ($number == NULL) return FALSE;
-  if (!is_numeric($number)) return FALSE;
-  return TRUE;
-}
+  $devel_generate_manager = \Drupal::service('plugin.manager.develgenerate');
+  $instance = $devel_generate_manager->createInstance($plugin_id, array());
 
-// Include devel_generate.inc.
-function drush_generate_include_devel() {
-  $path = drupal_get_path('module', 'devel_generate');
-  require_once($path .'/devel_generate.inc');
+  //Plugin instance suit params in order to fit for generateElements
+  $values = $instance->getDrushValues($params);
+  $instance->generateElements($values);
+  $instance->drushLog($values);
 }
diff --git a/devel_generate/devel_generate.fields.inc b/devel_generate/devel_generate.fields.inc
old mode 100644
new mode 100755
diff --git a/devel_generate/devel_generate.inc b/devel_generate/devel_generate.inc
deleted file mode 100644
index 7a5f4f6..0000000
--- a/devel_generate/devel_generate.inc
+++ /dev/null
@@ -1,657 +0,0 @@
-<?php
-
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Language\Language;
-
-/**
- * Generate some random users.
- *
- * @param $num
- *  Number of users to generate.
- * @param $kill
- *  Boolean that indicates if existing users should be removed first.
- * @param $age
- *  The max age of each randomly-generated user, in seconds.
- * @param $roles
- *  An array of role IDs that the users should receive.
- * @param $pass
- *  A string to be used as the password for the generated users.
- */
-function devel_create_users($num, $kill, $age = 0, $roles = array(), $pass = NULL) {
-  $url = parse_url($GLOBALS['base_url']);
-  if ($kill) {
-    $uids = db_select('users', 'u')
-            ->fields('u', array('uid'))
-            ->condition('uid', 1, '>')
-            ->execute()
-            ->fetchAllAssoc('uid');
-    user_delete_multiple(array_keys($uids));
-    drupal_set_message(format_plural(count($uids), '1 user deleted', '@count users deleted.'));
-  }
-
-  if ($num > 0) {
-    $names = array();
-    while (count($names) < $num) {
-      $name = devel_generate_word(mt_rand(6, 12));
-      $names[$name] = '';
-    }
-
-    if (empty($roles)) {
-      $roles = array(DRUPAL_AUTHENTICATED_RID);
-    }
-    foreach ($names as $name => $value) {
-      $edit = array(
-        'uid'     => NULL,
-        'name'    => $name,
-        'pass'    => $pass,
-        'mail'    => $name . '@' . $url['host'] . '.invalid',
-        'status'  => 1,
-        'created' => REQUEST_TIME - mt_rand(0, $age),
-        'roles' => drupal_map_assoc($roles),
-        'devel_generate' => TRUE // A flag to let hook_user_* know that this is a generated user.
-      );
-      $account = entity_create('user', $edit);
-
-      // Populate all core fields on behalf of field.module
-      module_load_include('inc', 'devel_generate', 'devel_generate.fields');
-      devel_generate_fields($account, 'user', 'user', 'register');
-      $account->save();
-    }
-  }
-  drupal_set_message(t('!num_users created.', array('!num_users' => format_plural($num, '1 user', '@count users'))));
-}
-
-
-/**
- * The main API function for creating content.
- *
- * See devel_generate_content_form() for the supported keys in
- * $form_state['values'].
- * Other modules may participate by form_alter() on that form and then handling
- * their data during hook_node_insert() or in their own submit handler for the
- * form.
- *
- * @param string $form_state
- * @return void
- */
-function devel_generate_content($form_state) {
-  if (!empty($form_state['values']['kill_content'])) {
-    devel_generate_content_kill($form_state['values']);
-  }
-
-  if (count($form_state['values']['node_types'])) {
-    // Generate nodes.
-    devel_generate_content_pre_node($form_state['values']);
-    $start = time();
-    for ($i = 1; $i <= $form_state['values']['num_nodes']; $i++) {
-      devel_generate_content_add_node($form_state['values']);
-      if (function_exists('drush_log') && $i % drush_get_option('feedback', 1000) == 0) {
-        $now = time();
-        drush_log(dt('Completed !feedback nodes (!rate nodes/min)', array('!feedback' => drush_get_option('feedback', 1000), '!rate' => (drush_get_option('feedback', 1000)*60)/($now-$start))), 'ok');
-        $start = $now;
-      }
-    }
-  }
-
-  devel_generate_set_message(format_plural($form_state['values']['num_nodes'], '1 node created.', 'Finished creating @count nodes'));
-}
-
-function devel_generate_add_comments(EntityInterface $node, $field, $users, $max_comments, $title_length = 8) {
-  $field_name = $field->getFieldName();
-  if ($node->{$field_name}->status >= COMMENT_OPEN) {
-    $num_comments = mt_rand(1, $max_comments);
-    for ($i = 1; $i <= $num_comments; $i++) {
-      switch ($i % 3) {
-        case 1:
-          $pid = db_query_range("SELECT cid FROM {comment} WHERE pid = 0 AND entity_id = :entity_id ORDER BY RAND()", 0, 1, array(':entity_id' => $node->id()))->fetchField();
-          break;
-        case 2:
-          $pid = db_query_range("SELECT cid FROM {comment} WHERE pid > 0 AND entity_id = :entity_id ORDER BY RAND()", 0, 1, array(':entity_id' => $node->id()))->fetchField();
-          break;
-        default:
-          $pid = 0;
-      }
-
-      $comment = entity_create('comment', array(
-        'entity_type' => $node->entityType(),
-        'entity_id' => $node->id(),
-        'field_id' => $node->entityType() . '__' . $field_name,
-        'name' => 'devel generate',
-        'mail' => 'devel_generate@example.com',
-        'timestamp' => mt_rand($node->created->value, REQUEST_TIME),
-        'subject' => substr(devel_create_greeking(mt_rand(2, $title_length), TRUE), 0, 63),
-        'uid' => $users[array_rand($users)],
-        'langcode' => Language::LANGCODE_NOT_SPECIFIED,
-        'pid' => !empty($pid) ? $pid : 0,
-      ));
-
-      //Populate all core fields on behalf of field.module
-      module_load_include('inc', 'devel_generate', 'devel_generate.fields');
-      devel_generate_fields($comment, 'comment', $comment->bundle());
-      $comment->save();
-    }
-  }
-}
-
-function devel_generate_vocabs($records, $maxlength = 12, $types = array('page', 'article')) {
-  $vocs = array();
-
-  // Insert new data:
-  for ($i = 1; $i <= $records; $i++) {
-    $name = devel_generate_word(mt_rand(2, $maxlength));
-    $vocabulary = entity_create('taxonomy_vocabulary', array(
-      'name' => $name,
-      'vid' => drupal_strtolower($name),
-      'langcode' => Language::LANGCODE_NOT_SPECIFIED,
-      'description' => "description of $name",
-      'hierarchy' => 1,
-      'weight' => mt_rand(0, 10),
-      'multiple' => 1,
-      'required' => 0,
-      'relations' => 1,
-    ));
-    $vocabulary->save();
-    $vocs[] = $vocabulary->name;
-
-    unset($vocabulary);
-  }
-  return $vocs;
-}
-
-/**
- * Generates taxonomy terms for a list of given vocabularies.
- *
- * @param $records
- *   int number of terms to create in total.
- * @param $vocabs
- *   array list of vocabs to populate.
- * @param $maxlength
- *   int maximum length per term.
- * @return
- *   array the list of names of the created terms.
- */
-function devel_generate_terms($records, $vocabs, $maxlength = 12) {
-  $terms = array();
-
-  // Insert new data:
-  $max = db_query('SELECT MAX(tid) FROM {taxonomy_term_data}')->fetchField();
-  $start = time();
-  for ($i = 1; $i <= $records; $i++) {
-    $values = array();
-    switch ($i % 2) {
-      case 1:
-        // Set vid and vocabulary_machine_name properties.
-        $vocab = $vocabs[array_rand($vocabs)];
-        $values['vid'] = $vocab->vid;
-        $values['vocabulary_machine_name'] = $vocab->vid;
-        $values['parent'] = array(0);
-        break;
-      default:
-        while (TRUE) {
-          // Keep trying to find a random parent.
-          $candidate = mt_rand(1, $max);
-          $query = db_select('taxonomy_term_data', 't');
-          $parent = $query
-                    ->fields('t', array('tid', 'vid'))
-                    ->condition('t.vid', array_keys($vocabs), 'IN')
-                    ->condition('t.tid', $candidate, '>=')
-                    ->range(0,1)
-                    ->execute()
-                    ->fetchAssoc();
-          if ($parent['tid']) {
-            break;
-          }
-        }
-        $values['parent'] = array($parent['tid']);
-        // Slight speedup due to this property being set.
-        $values['vocabulary_machine_name'] = $parent['vid'];
-        $values['vid'] = $parent['vid'];
-        break;
-    }
-
-    $values['name'] = devel_generate_word(mt_rand(2, $maxlength));
-    $values['description'] = "description of " . $values['name'];
-    $values['format'] = filter_fallback_format();
-    $values['weight'] = mt_rand(0, 10);
-    $values['langcode'] = Language::LANGCODE_NOT_SPECIFIED;
-    $term = entity_create('taxonomy_term', $values);
-
-    // Populate all core fields on behalf of field.module
-    module_load_include('inc', 'devel_generate', 'devel_generate.fields');
-    devel_generate_fields($term, 'taxonomy_term', $values['vocabulary_machine_name']);
-
-    if ($status = $term->save()) {
-      $max += 1;
-      if (function_exists('drush_log')) {
-        $feedback = drush_get_option('feedback', 1000);
-        if ($i % $feedback == 0) {
-          $now = time();
-          drush_log(dt('Completed !feedback terms (!rate terms/min)', array('!feedback' => $feedback, '!rate' => $feedback*60 / ($now-$start) )), 'ok');
-          $start = $now;
-        }
-      }
-
-      // Limit memory usage. Only report first 20 created terms.
-      if ($i < 20) {
-        $terms[] = $term->name->value;
-      }
-
-      unset($term);
-    }
-  }
-  return $terms;
-}
-
-// TODO: use taxonomy_get_entries once that exists.
-function devel_generate_get_terms($vids) {
-  return db_select('taxonomy_term_data', 'td')
-           ->fields('td', array('tid'))
-           ->condition('vid', $vids, 'IN')
-           ->orderBy('tid', 'ASC')
-           ->execute()
-           ->fetchCol('tid');
-}
-
-/**
- * Deletes all terms of a vocabulary.
- *
- * @param $vid
- *   int a vocabulary vid.
- */
-function devel_generate_delete_vocabulary_terms($vid) {
-  $tids = array();
-  foreach (taxonomy_get_tree($vid) as $term) {
-    $tids[] = $term->tid;
-  }
-  entity_delete_multiple('taxonomy_term', $tids);;
-}
-
-/**
- * Deletes all vocabularies.
- */
-function devel_generate_delete_vocabularies() {
-  foreach (entity_load_multiple('taxonomy_vocabulary') as $vid => $vocabulary) {
-    $vocabulary->delete();
-  }
-}
-
-/**
- * Deletes custom generated menus
- */
-function devel_generate_delete_menus() {
-  if (module_exists('menu')) {
-    foreach (menu_get_menus(FALSE) as $menu => $menu_title) {
-      if (strpos($menu, 'devel-') === 0) {
-        menu_load($menu)->delete();
-      }
-    }
-  }
-  // Delete menu links generated by devel.
-  $result = db_select('menu_links', 'm')
-    ->fields('m', array('mlid'))
-    ->condition('m.menu_name', 'devel', '<>')
-    // Look for the serialized version of 'devel' => TRUE.
-    ->condition('m.options', '%' . db_like('s:5:"devel";b:1') . '%', 'LIKE')
-    ->execute();
-  foreach ($result as $link) {
-    menu_link_delete($link->mlid);
-  }
-}
-
-/**
- * Generates new menus.
- */
-function devel_generate_menus($num_menus, $title_length = 12) {
-  $menus = array();
-
-  if (!module_exists('menu')) {
-    $num_menus = 0;
-  }
-
-  for ($i = 1; $i <= $num_menus; $i++) {
-    $menu = array();
-    $menu['label'] = devel_generate_word(mt_rand(2, max(2, $title_length)));
-    $menu['id'] = 'devel-' . drupal_strtolower($menu['label']);
-    $menu['description'] = t('Description of @name', array('@name' => $menu['label']));
-    $new_menu = entity_create('menu', $menu);
-    $new_menu->save();
-    $menus[$new_menu->id()] = $new_menu->label();
-  }
-
-  return $menus;
-}
-
-/**
- * Generates menu links in a tree structure.
- */
-function devel_generate_links($num_links, $menus, $title_length, $link_types, $max_depth, $max_width) {
-  $links = array();
-  $menus = array_keys(array_filter($menus));
-  $link_types = array_keys(array_filter($link_types));
-
-  $nids = array();
-  for ($i = 1; $i <= $num_links; $i++) {
-    // Pick a random menu.
-    $menu_name = $menus[array_rand($menus)];
-    // Build up our link.
-    $link = entity_create('menu_link', array(
-      'menu_name'   => $menu_name,
-      'options'     => array('devel' => TRUE),
-      'weight'      => mt_rand(-50, 50),
-      'mlid'        => 0,
-      'link_title'  => devel_generate_word(mt_rand(2, max(2, $title_length))),
-    ));
-    $link->options['attributes']['title'] = t('Description of @title.', array('@title' => $link->link_title));
-
-    // For the first $max_width items, make first level links.
-    if ($i <= $max_width) {
-      $depth = 0;
-    }
-    else {
-      // Otherwise, get a random parent menu depth.
-      $depth = mt_rand(1, max(1, $max_depth - 1));
-    }
-    // Get a random parent link from the proper depth.
-    do {
-      $link->plid = db_select('menu_links', 'm')
-        ->fields('m', array('mlid'))
-        ->condition('m.menu_name', $menus, 'IN')
-        ->condition('m.depth', $depth)
-        ->range(0, 1)
-        ->orderRandom()
-        ->execute()
-        ->fetchField();
-      $depth--;
-    } while (!$link->plid && $depth > 0);
-    if (!$link->plid) {
-      $link->plid = 0;
-    }
-
-    $link_type = array_rand($link_types);
-    switch ($link_types[$link_type]) {
-      case 'node':
-        // Grab a random node ID.
-        $select = db_select('node_field_data', 'n')
-          ->fields('n', array('nid', 'title'))
-          ->condition('n.status', 1)
-          ->range(0, 1)
-          ->orderRandom();
-        // Don't put a node into the menu twice.
-        if (!empty($nids[$menu_name])) {
-          $select->condition('n.nid', $nids[$menu_name], 'NOT IN');
-        }
-        $node = $select->execute()->fetchAssoc();
-        if (isset($node['nid'])) {
-          $nids[$menu_name][] = $node['nid'];
-          $link->link_path = $link->router_path = 'node/' . $node['nid'];
-          $link->link_title = $node['title'];
-          break;
-        }
-      case 'external':
-        $link->link_path = 'http://www.example.com/';
-        break;
-      case 'front':
-        $link->link_path = $link->router_path = '<front>';
-        break;
-      default:
-        $link->devel_link_type = $link_type;
-        break;
-    }
-
-    $link->save();
-
-    $links[$link->id()] = $link->link_title;
-  }
-
-  return $links;
-}
-
-function devel_generate_word($length){
-  mt_srand((double)microtime()*1000000);
-
-  $vowels = array("a", "e", "i", "o", "u");
-  $cons = array("b", "c", "d", "g", "h", "j", "k", "l", "m", "n", "p", "r", "s", "t", "u", "v", "w", "tr",
-  "cr", "br", "fr", "th", "dr", "ch", "ph", "wr", "st", "sp", "sw", "pr", "sl", "cl", "sh");
-
-  $num_vowels = count($vowels);
-  $num_cons = count($cons);
-  $word = '';
-
-  while(strlen($word) < $length){
-    $word .= $cons[mt_rand(0, $num_cons - 1)] . $vowels[mt_rand(0, $num_vowels - 1)];
-  }
-
-  return substr($word, 0, $length);
-}
-
-function devel_create_content($type = NULL) {
-  $nparas = mt_rand(1,12);
-  $type = empty($type) ? mt_rand(0,3) : $type;
-
-  $output = "";
-  switch($type % 3) {
-    // MW: This appears undesireable. Was giving <p> in text fields
-    // case 1: // html
-    //       for ($i = 1; $i <= $nparas; $i++) {
-    //         $output .= devel_create_para(mt_rand(10,60),1);
-    //       }
-    //       break;
-    //
-    //     case 2: // brs only
-    //       for ($i = 1; $i <= $nparas; $i++) {
-    //         $output .= devel_create_para(mt_rand(10,60),2);
-    //       }
-    //       break;
-
-    default: // plain text
-      for ($i = 1; $i <= $nparas; $i++) {
-        $output .= devel_create_para(mt_rand(10,60)) ."\n\n";
-      }
-  }
-
-  return $output;
-}
-
-function devel_create_para($words, $type = 0) {
-  $output = '';
-  switch ($type) {
-    case 1:
-      $output .= "<p>" . devel_create_greeking($words)  . "</p>";
-      break;
-
-    case 2:
-      $output .= devel_create_greeking($words) . "<br />";
-      break;
-
-    default:
-      $output .= devel_create_greeking($words);
-  }
-  return $output;
-}
-
-function devel_create_greeking($word_count, $title = FALSE) {
-  $dictionary = array("abbas", "abdo", "abico", "abigo", "abluo", "accumsan",
-    "acsi", "ad", "adipiscing", "aliquam", "aliquip", "amet", "antehabeo",
-    "appellatio", "aptent", "at", "augue", "autem", "bene", "blandit",
-    "brevitas", "caecus", "camur", "capto", "causa", "cogo", "comis",
-    "commodo", "commoveo", "consectetuer", "consequat", "conventio", "cui",
-    "damnum", "decet", "defui", "diam", "dignissim", "distineo", "dolor",
-    "dolore", "dolus", "duis", "ea", "eligo", "elit", "enim", "erat",
-    "eros", "esca", "esse", "et", "eu", "euismod", "eum", "ex", "exerci",
-    "exputo", "facilisi", "facilisis", "fere", "feugiat", "gemino",
-    "genitus", "gilvus", "gravis", "haero", "hendrerit", "hos", "huic",
-    "humo", "iaceo", "ibidem", "ideo", "ille", "illum", "immitto",
-    "importunus", "imputo", "in", "incassum", "inhibeo", "interdico",
-    "iriure", "iusto", "iustum", "jugis", "jumentum", "jus", "laoreet",
-    "lenis", "letalis", "lobortis", "loquor", "lucidus", "luctus", "ludus",
-    "luptatum", "macto", "magna", "mauris", "melior", "metuo", "meus",
-    "minim", "modo", "molior", "mos", "natu", "neo", "neque", "nibh",
-    "nimis", "nisl", "nobis", "nostrud", "nulla", "nunc", "nutus", "obruo",
-    "occuro", "odio", "olim", "oppeto", "os", "pagus", "pala", "paratus",
-    "patria", "paulatim", "pecus", "persto", "pertineo", "plaga", "pneum",
-    "populus", "praemitto", "praesent", "premo", "probo", "proprius",
-    "quadrum", "quae", "qui", "quia", "quibus", "quidem", "quidne", "quis",
-    "ratis", "refero", "refoveo", "roto", "rusticus", "saepius",
-    "sagaciter", "saluto", "scisco", "secundum", "sed", "si", "similis",
-    "singularis", "sino", "sit", "sudo", "suscipere", "suscipit", "tamen",
-    "tation", "te", "tego", "tincidunt", "torqueo", "tum", "turpis",
-    "typicus", "ulciscor", "ullamcorper", "usitas", "ut", "utinam",
-    "utrum", "uxor", "valde", "valetudo", "validus", "vel", "velit",
-    "veniam", "venio", "vereor", "vero", "verto", "vicis", "vindico",
-    "virtus", "voco", "volutpat", "vulpes", "vulputate", "wisi", "ymo",
-    "zelus");
-  $dictionary_flipped = array_flip($dictionary);
-
-  $greeking = '';
-
-  if (!$title) {
-    $words_remaining = $word_count;
-    while ($words_remaining > 0) {
-      $sentence_length = mt_rand(3, 10);
-      $words = array_rand($dictionary_flipped, $sentence_length);
-      $sentence = implode(' ', $words);
-      $greeking .= ucfirst($sentence) . '. ';
-      $words_remaining -= $sentence_length;
-    }
-  }
-  else {
-    // Use slightly different method for titles.
-    $words = array_rand($dictionary_flipped, $word_count);
-    $words = is_array($words) ? implode(' ', $words) : $words;
-    $greeking = ucwords($words);
-  }
-
-  // Work around possible php garbage collection bug. Without an unset(), this
-  // function gets very expensive over many calls (php 5.2.11).
-  unset($dictionary, $dictionary_flipped);
-  return trim($greeking);
-}
-
-function devel_get_users() {
-  $users = array();
-  $result = db_query_range("SELECT uid FROM {users}", 0, 50);
-  foreach ($result as $record) {
-    $users[] = $record->uid;
-  }
-  return $users;
-}
-
-/**
- * Generate statistics information for a node.
- *
- * @param $node
- *   A node object.
- */
-function devel_generate_add_statistics($node) {
-  $statistic = array(
-    'nid' => $node->id(),
-    'totalcount' => mt_rand(0, 500),
-    'timestamp' => REQUEST_TIME - mt_rand(0, $node->created),
-  );
-  $statistic['daycount'] = mt_rand(0, $statistic['totalcount']);
-  db_insert('node_counter')->fields($statistic)->execute();
-}
-
-/**
- * Handle the devel_generate_content_form request to kill all of the content.
- * This is used by both the batch and non-batch branches of the code.
- *
- * @param $num
- *   array of options obtained from devel_generate_content_form.
- */
-function devel_generate_content_kill($values) {
-  $results = db_select('node', 'n')
-              ->fields('n', array('nid'))
-              ->condition('type', $values['node_types'], 'IN')
-              ->execute();
-  foreach ($results as $result) {
-    $nids[] = $result->nid;
-  }
-
-  if (!empty($nids)) {
-    entity_delete_multiple('node', $nids);
-    drupal_set_message(t('Deleted %count nodes.', array('%count' => count($nids))));
-  }
-}
-
-/**
- * Pre-process the devel_generate_content_form request.  This is needed so
- * batch api can get the list of users once.  This is used by both the batch
- * and non-batch branches of the code.
- *
- * @param $num
- *   array of options obtained from devel_generate_content_form.
- */
-function devel_generate_content_pre_node(&$results) {
-  // Get user id.
-  $users = devel_get_users();
-  $users = array_merge($users, array('0'));
-  $results['users'] = $users;
-}
-
-/**
- * Create one node. Used by both batch and non-batch code branches.
- *
- * @param $num
- *   array of options obtained from devel_generate_content_form.
- */
-function devel_generate_content_add_node(&$results) {
-  if (!isset($results['time_range'])) {
-    $results['time_range'] = 0;
-  }
-  $users = $results['users'];
-
-  $node_type = array_rand(array_filter($results['node_types']));
-  $type = node_type_load($node_type);
-  $uid = $users[array_rand($users)];
-
-  $edit_node = array(
-    'nid' => NULL,
-    'type' => $node_type,
-    'uid' => $uid,
-    'revision' => mt_rand(0, 1),
-    'status' => TRUE,
-    'promote' => mt_rand(0, 1),
-    'created' => REQUEST_TIME - mt_rand(0, $results['time_range']),
-    'langcode' => devel_generate_get_langcode($results),
-  );
-  if ($type->has_title) {
-    // We should not use the random function if the value is not random
-    if ($results['title_length'] < 2) {
-      $edit_node['title'] = devel_create_greeking(1, TRUE);
-    }
-    else {
-      $edit_node['title'] = devel_create_greeking(mt_rand(1, $results['title_length']), TRUE);
-    }
-  }
-  else {
-    $edit_node['title'] = '';
-  }
-  $node = entity_create('node', $edit_node);
-
-  // A flag to let hook_node_insert() implementations know that this is a
-  // generated node.
-  $node->devel_generate = $results;
-
-  // Populate all core fields on behalf of field.module
-  module_load_include('inc', 'devel_generate', 'devel_generate.fields');
-  devel_generate_fields($node, 'node', $node->bundle());
-
-  // See devel_generate_node_insert() for actions that happen before and after
-  // this save.
-  $node->save();
-}
-
-/*
- * Determine language based on $results.
- */
-function devel_generate_get_langcode($results) {
-  if (isset($results['add_language'])) {
-    $langcodes = $results['add_language'];
-    $langcode = $langcodes[array_rand($langcodes)];
-  }
-  else {
-    $langcode = language_default()->id;
-  }
-  return $langcode == 'en' ? Language::LANGCODE_NOT_SPECIFIED : $langcode;
-}
diff --git a/devel_generate/devel_generate.info.yml b/devel_generate/devel_generate.info.yml
old mode 100644
new mode 100755
diff --git a/devel_generate/devel_generate.module b/devel_generate/devel_generate.module
old mode 100644
new mode 100755
index 827e5f4..1d1ecc5
--- a/devel_generate/devel_generate.module
+++ b/devel_generate/devel_generate.module
@@ -8,35 +8,18 @@ use Drupal\field\Field;
  * Implements hook_menu().
  */
 function devel_generate_menu() {
+
   $items = array();
 
-  $items['admin/config/development/generate/user'] = array(
-    'title' => 'Generate users',
-    'description' => 'Generate a given number of users. Optionally delete current users.',
-    'route_name' => 'devel_generate.user',
-  );
-  $items['admin/config/development/generate/content'] = array(
-    'title' => 'Generate content',
-    'description' => 'Generate a given number of nodes and comments. Optionally delete current items.',
-    'route_name' => 'devel_generate.content',
-  );
-  if (module_exists('taxonomy')) {
-    $items['admin/config/development/generate/taxonomy'] = array(
-      'title' => 'Generate terms',
-      'description' => 'Generate a given number of terms. Optionally delete current terms.',
-      'route_name' => 'devel_generate.taxonomy_term',
-    );
-    $items['admin/config/development/generate/vocabs'] = array(
-      'title' => 'Generate vocabularies',
-      'description' => 'Generate a given number of vocabularies. Optionally delete current vocabularies.',
-      'route_name' => 'devel_generate.vocabulary',
+  $devel_generate_plugins = $devel_generate_manager = \Drupal::service('plugin.manager.develgenerate')->getDefinitions();
+  foreach ($devel_generate_plugins as $id => $plugin) {
+    $type_url_str = str_replace('_', '-', $id);
+    $items["admin/config/development/generate/$type_url_str"] = array(
+      'title' => "Generate $id",
+      'description' => 'Generate a given number of entities.',
+      'route_name' => "devel_generate.$id",
     );
   }
-  $items['admin/config/development/generate/menu'] = array(
-    'title' => 'Generate menus',
-    'description' => 'Generate a given number of menus and menu links. Optionally delete current menus.',
-    'route_name' => 'devel_generate.menu',
-  );
 
   return $items;
 }
diff --git a/devel_generate/devel_generate.routing.yml b/devel_generate/devel_generate.routing.yml
deleted file mode 100644
index 007f8e4..0000000
--- a/devel_generate/devel_generate.routing.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-devel_generate.user:
-  path: '/admin/config/development/generate/user'
-  defaults:
-    _form: '\Drupal\devel_generate\Form\GenerateUser'
-  requirements:
-    _permission: 'administer users'
-
-devel_generate.content:
-  path: '/admin/config/development/generate/content'
-  defaults:
-    _form: '\Drupal\devel_generate\Form\GenerateContent'
-  requirements:
-    _permission: 'administer nodes'
-
-devel_generate.menu:
-  path: '/admin/config/development/generate/menu'
-  defaults:
-    _form: '\Drupal\devel_generate\Form\GenerateMenu'
-  requirements:
-    _permission: 'administer menu'
-
-devel_generate.taxonomy_term:
-  path: '/admin/config/development/generate/taxonomy'
-  defaults:
-    _form: '\Drupal\devel_generate\Form\GenerateTerm'
-  options:
-    _module_exists: 'taxonomy'
-  requirements:
-    _permission: 'administer taxonomy'
-
-devel_generate.vocabulary:
-  path: '/admin/config/development/generate/vocabs'
-  defaults:
-    _form: '\Drupal\devel_generate\Form\GenerateVocabulary'
-  options:
-    _module_exists: 'taxonomy'
-  requirements:
-    _permission: 'administer taxonomy'
diff --git a/devel_generate/devel_generate.services.yml b/devel_generate/devel_generate.services.yml
new file mode 100755
index 0000000..5841c42
--- /dev/null
+++ b/devel_generate/devel_generate.services.yml
@@ -0,0 +1,10 @@
+services:
+  plugin.manager.develgenerate:
+    class: Drupal\devel_generate\DevelGeneratePluginManager
+    arguments: ['@container.namespaces']
+
+  develgenerate.subscriber:
+    class: Drupal\devel_generate\Routing\DevelGenerateRouteSubscriber
+    arguments: ['@router.route_provider']
+    tags:
+      - { name: event_subscriber }
\ No newline at end of file
diff --git a/devel_generate/devel_generate_batch.inc b/devel_generate/devel_generate_batch.inc
old mode 100644
new mode 100755
diff --git a/devel_generate/email.devel_generate.inc b/devel_generate/email.devel_generate.inc
deleted file mode 100644
index 2e22fff..0000000
--- a/devel_generate/email.devel_generate.inc
+++ /dev/null
@@ -1,29 +0,0 @@
-<?php
-/**
- * @file
- * Support file for generating email field content.
- */
-
-function email_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  if (isset($plugin_definition['multiple_values']) && $plugin_definition['multiple_values'] === TRUE) {
-    return devel_generate_multiple('_email_devel_generate', $object, $instance, $plugin_definition, $form_display_options);
-  }
-  else {
-    return _email_devel_generate($object, $instance, $plugin_definition, $form_display_options);
-  }
-}
-
-function _email_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  $object_field = array();
-
-  // Set of possible top-level domains.
-  $tlds = array('com', 'net', 'gov', 'org', 'edu', 'biz', 'info');
-
-  // Set random lengths for the user and domain as the email field doesn't have
-  // any setting for length.
-  $user_length = mt_rand(5, 10);
-  $domain_length = mt_rand(7, 15);
-
-  $object_field['value'] = devel_generate_word($user_length) . '@' . devel_generate_word($domain_length) . '.' . $tlds[mt_rand(0, (sizeof($tlds)-1))];
-  return $object_field;
-}
diff --git a/devel_generate/file.devel_generate.inc b/devel_generate/file.devel_generate.inc
deleted file mode 100644
index f466a1d..0000000
--- a/devel_generate/file.devel_generate.inc
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-
-function file_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  if (isset($plugin_definition['multiple_values']) && $plugin_definition['multiple_values'] === TRUE) {
-    return devel_generate_multiple('_file_devel_generate', $object, $instance, $plugin_definition, $form_display_options);
-  }
-  else {
-    return _file_devel_generate($object, $instance, $plugin_definition, $form_display_options);
-  }
-}
-
-function _file_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  static $file;
-  $settings = $instance->getFieldSettings();
-
-  if (empty($file)) {
-    if ($path = devel_generate_textfile()) {
-      $source = new stdClass();
-      $source->uri = $path;
-      $source->uid = 1; // TODO: randomize? use case specific.
-      $source->filemime = 'text/plain';
-      $source->filename = drupal_basename($path);
-      $destination_dir = $settings['uri_scheme'] . '://' . $settings['file_directory'];
-      file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY);
-      $destination = $destination_dir . '/' . basename($path);
-      $file = file_move($source, $destination, FILE_CREATE_DIRECTORY);
-    }
-    else {
-      return FALSE;
-    }
-  }
-  if (!$file) {
-    // In case a previous file operation failed or no file is set, return FALSE
-    return FALSE;
-  }
-  else {
-    $object_field['target_id'] = $file->id();
-    $object_field['display'] = $settings['display_default'];
-    $object_field['description'] = devel_create_greeking(10);
-
-    return $object_field;
-  }
-}
-
-/**
- * Private function for generating a random text file.
- */
-function devel_generate_textfile($filesize = 1024) {
-  if ($tmp_file = drupal_tempnam('temporary://', 'filefield_')) {
-    $destination = $tmp_file . '.txt';
-    file_unmanaged_move($tmp_file, $destination);
-
-    $fp = fopen($destination, 'w');
-    fwrite($fp, str_repeat('01', $filesize/2));
-    fclose($fp);
-
-    return $destination;
-  }
-}
diff --git a/devel_generate/image.devel_generate.inc b/devel_generate/image.devel_generate.inc
deleted file mode 100644
index 91a5410..0000000
--- a/devel_generate/image.devel_generate.inc
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-
-define('DEVEL_GENERATE_IMAGE_MAX', 5);
-
-function image_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  if (function_exists('imagejpeg')) {
-    $devel_generate_image_function = variable_get('devel_generate_image_function', '_image_devel_generate');
-    if (!function_exists($devel_generate_image_function)) {
-      $devel_generate_image_function = '_image_devel_generate';
-    }
-    if (isset($plugin_definition['multiple_values']) && $plugin_definition['multiple_values'] === TRUE) {
-      return devel_generate_multiple($devel_generate_image_function, $object, $instance, $plugin_definition, $form_display_options);
-    }
-    else {
-      return $devel_generate_image_function($object, $instance, $plugin_definition, $form_display_options);
-    }
-  }
-}
-
-function _image_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  $object_field = array();
-  static $images = array();
-  $settings = $instance->getFieldSettings();
-
-  $min_resolution = empty($settings['min_resolution']) ? '100x100' : $settings['min_resolution'];
-  $max_resolution = empty($settings['max_resolution']) ? '600x600' : $settings['max_resolution'];
-  $extensions = array_intersect(explode(' ', $settings['file_extensions']), array('png', 'gif', 'jpg', 'jpeg'));
-  $extension = array_rand(drupal_map_assoc($extensions));
-  // Generate a max of 5 different images.
-  if (!isset($images[$extension][$min_resolution][$max_resolution]) || count($images[$extension][$min_resolution][$max_resolution]) <= DEVEL_GENERATE_IMAGE_MAX) {
-    if ($path = devel_generate_image($extension, $min_resolution, $max_resolution)) {
-      $account = user_load(1);
-      $image = entity_create('file', array());
-      $image->setFileUri($path);
-      $image->setOwner($account);
-      $image->setMimeType('image/' . pathinfo($path, PATHINFO_EXTENSION));
-      $image->setFileName(drupal_basename($path));
-      $destination_dir = $settings['uri_scheme'] . '://' . $settings['file_directory'];
-      file_prepare_directory($destination_dir, FILE_CREATE_DIRECTORY);
-      $destination = $destination_dir . '/' . basename($path);
-      $file = file_move($image, $destination, FILE_CREATE_DIRECTORY);
-      $images[$extension][$min_resolution][$max_resolution][$file->id()] = $file;
-    }
-    else {
-      return FALSE;
-    }
-  }
-  else {
-    // Select one of the images we've already generated for this field.
-    $image_index = array_rand($images[$extension][$min_resolution][$max_resolution]);
-    $file = $images[$extension][$min_resolution][$max_resolution][$image_index];
-  }
-
-  $object_field['target_id'] = $file->id();
-  $object_field['alt'] = devel_create_greeking(4);
-  $object_field['title'] = devel_create_greeking(4);
-  return $object_field;
-}
-
-/**
- * Private function for creating a random image.
- *
- * This function only works with the GD toolkit. ImageMagick is not supported.
- */
-function devel_generate_image($extension = 'png', $min_resolution, $max_resolution) {
-  if ($tmp_file = drupal_tempnam('temporary://', 'imagefield_')) {
-    $destination = $tmp_file . '.' . $extension;
-    file_unmanaged_move($tmp_file, $destination, FILE_CREATE_DIRECTORY);
-
-    $min = explode('x', $min_resolution);
-    $max = explode('x', $max_resolution);
-
-    $width = rand((int)$min[0], (int)$max[0]);
-    $height = rand((int)$min[1], (int)$max[1]);
-
-    // Make an image split into 4 sections with random colors.
-    $im = imagecreate($width, $height);
-    for ($n = 0; $n < 4; $n++) {
-      $color = imagecolorallocate($im, rand(0, 255), rand(0, 255), rand(0, 255));
-      $x = $width/2 * ($n % 2);
-      $y = $height/2 * (int) ($n >= 2);
-      imagefilledrectangle($im, $x, $y, $x + $width/2, $y + $height/2, $color);
-    }
-
-    // Make a perfect circle in the image middle.
-    $color = imagecolorallocate($im, rand(0, 255), rand(0, 255), rand(0, 255));
-    $smaller_dimension = min($width, $height);
-    $smaller_dimension = ($smaller_dimension % 2) ? $smaller_dimension : $smaller_dimension;
-    imageellipse($im, $width/2, $height/2, $smaller_dimension, $smaller_dimension, $color);
-
-    $save_function = 'image'. ($extension == 'jpg' ? 'jpeg' : $extension);
-    $save_function($im, drupal_realpath($destination));
-    return $destination;
-  }
-}
diff --git a/devel_generate/lib/Drupal/devel_generate/Annotation/DevelGenerate.php b/devel_generate/lib/Drupal/devel_generate/Annotation/DevelGenerate.php
new file mode 100755
index 0000000..77642d9
--- /dev/null
+++ b/devel_generate/lib/Drupal/devel_generate/Annotation/DevelGenerate.php
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\devel_generate\Annotation\DevelGenerate.
+ */
+
+namespace Drupal\devel_generate\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines a DevelGenerate annotation object.
+ *
+ * DevelGenerate handle the bulk creation of entites.
+ *
+ * Additional annotation keys for formatters can be defined in
+ * hook_devel_generate_info_alter().
+ *
+ * @Annotation
+ *
+ * @see \Drupal\devel_generate\DevelGeneratePluginManager
+ * @see \Drupal\devel_generate\DevelGenerateBaseInterface
+ */
+class DevelGenerate extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The name of the DevelGenerate class.
+   *
+   * This is not provided manually, it will be added by the discovery mechanism.
+   *
+   * @var string
+   */
+  public $class;
+
+  /**
+   * An array whose keys are the names of the settings available to the
+   * DevelGenerate settingsForm, and whose values are the default values for those settings.
+   *
+   * @var array
+   */
+  public $settings = array();
+
+  /**
+   * An array whose keys are the names of the settings available to the
+   * DevelGenerate drush command.
+   *
+   * @var array
+   */
+
+  public $drushSettings = array();
+
+  /**
+   * An array whose keys are the names of the args available to the
+   * DevelGenerate drush command.
+   *
+   * @var array
+   */
+  public $drushArgs = array();
+
+}
diff --git a/devel_generate/lib/Drupal/devel_generate/DevelGenerateBase.php b/devel_generate/lib/Drupal/devel_generate/DevelGenerateBase.php
new file mode 100755
index 0000000..896860e
--- /dev/null
+++ b/devel_generate/lib/Drupal/devel_generate/DevelGenerateBase.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace Drupal\devel_generate;
+
+use Drupal\Component\Plugin\PluginBase;
+
+abstract class DevelGenerateBase extends PluginBase implements DevelGenerateBaseInterface {
+
+  /**
+   * The plugin settings.
+   *
+   * @var array
+   */
+  protected $settings = array();
+
+  /**
+   * Whether default settings have been merged into the current $settings.
+   *
+   * @var bool
+   */
+  protected $defaultSettingsMerged = FALSE;
+
+  /**
+   * Implements Drupal\devel_generate\DevelGenerateBaseInterface::getSetting().
+   */
+  public function getSetting($key) {
+    // Merge defaults if we have no value for the key.
+    if (!$this->defaultSettingsMerged && !array_key_exists($key, $this->settings)) {
+      $this->mergeDefaults();
+    }
+    return isset($this->settings[$key]) ? $this->settings[$key] : NULL;
+  }
+
+  /**
+   * Merges default settings values into $settings.
+   */
+  protected function mergeDefaults() {
+    $this->settings += $this->getDefaultSettings();
+    $this->defaultSettingsMerged = TRUE;
+  }
+
+  /**
+   * Implements Drupal\devel_generate\DevelGenerateBaseInterface::getDefaultSettings().
+   */
+  public function getDefaultSettings() {
+    $definition = $this->getPluginDefinition();
+    return $definition['settings'];
+  }
+
+  /**
+   * Implements Drupal\devel_generate\DevelGenerateBaseInterface::settingsForm().
+   */
+  public function settingsForm(array $form, array &$form_state) {
+    return array();
+  }
+
+  /**
+   * Implements Drupal\devel_generate\DevelGenerateBaseInterface::generate().
+   */
+  public function generate(array $values) {
+    $this->generateElements($values);
+    drupal_set_message("Generate process complete");
+  }
+
+  /**
+   * Implements Drupal\devel_generate\DevelGenerateBaseInterface::getDrushValues().
+   */
+  public function getDrushValues($args) {
+
+  }
+
+  /**
+   * Implements Drupal\devel_generate\DevelGenerateBaseInterface::drushLog().
+   */
+  public function drushLog($values = array()) {
+
+  }
+}
diff --git a/devel_generate/lib/Drupal/devel_generate/DevelGenerateBaseInterface.php b/devel_generate/lib/Drupal/devel_generate/DevelGenerateBaseInterface.php
new file mode 100755
index 0000000..3bccb4c
--- /dev/null
+++ b/devel_generate/lib/Drupal/devel_generate/DevelGenerateBaseInterface.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\devel_generate\DevelGenerateInterface.
+ */
+
+namespace Drupal\devel_generate;
+use Drupal\Component\Plugin\PluginInspectionInterface;
+
+/**
+ * Base interface definition for "DevelGenerate" plugins.
+ *
+ * This interface details base wrapping methods that most DevelGenerate implementations
+ * will want to directly inherit from Drupal\devel_generate\DevelGenerateBase.
+ *
+ * DevelGenerate impementationa plugins should developing settingsForm() and generateElements()
+ * to achieve its own behaviour.
+ *
+ */
+interface DevelGenerateBaseInterface extends PluginInspectionInterface {
+
+  /**
+   * Returns the array of settings, including defaults for missing settings.
+   *
+   * @return array
+   *   The array of settings.
+   */
+  public function getSetting($key);
+
+  /**
+   * Returns the default settings for the plugin.
+   *
+   * @return array
+   *   The array of default setting values, keyed by setting names.
+   */
+  public function getDefaultSettings();
+
+  /**
+   * Returns the form for the plugin.
+   *
+   * @return array
+   *   The array of default setting values, keyed by setting names.
+   */
+  public function settingsForm(array $form, array &$form_state);
+
+  /**
+   * Execute the instructions in common for all DevelGenerate plugin
+   *
+   * @param array $values
+   *   The input values from the settings form.
+   */
+  public function generate(array $values);
+
+  /**
+   * Execute the concrete instructions for each DevelGenerate plugin
+   *
+   * @param array $values
+   *   The input values from the settings form.
+   */
+  public function generateElements(array $values);
+
+
+  /**
+   * Responsible for manage Drush settings.
+   */
+  public function getDrushValues($args);
+
+  /**
+   * Responsible for show drush log message.
+   */
+  public function drushLog($values = array());
+}
diff --git a/devel_generate/lib/Drupal/devel_generate/DevelGenerateFactory.php b/devel_generate/lib/Drupal/devel_generate/DevelGenerateFactory.php
new file mode 100755
index 0000000..f1d5ba7
--- /dev/null
+++ b/devel_generate/lib/Drupal/devel_generate/DevelGenerateFactory.php
@@ -0,0 +1,22 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\devel_generate\DevelGenerateFactory.
+ */
+
+namespace Drupal\devel_generate;
+
+use Drupal\Component\Plugin\Factory\DefaultFactory;
+
+/**
+ * Factory class for the ElementGenerate plugin type.
+ * Not necessary at the moment.
+ */
+class DevelGenerateFactory extends DefaultFactory {
+
+  /**
+   * {@inheritdoc}
+   */
+
+}
\ No newline at end of file
diff --git a/devel_generate/lib/Drupal/devel_generate/DevelGeneratePluginManager.php b/devel_generate/lib/Drupal/devel_generate/DevelGeneratePluginManager.php
new file mode 100755
index 0000000..b6a5537
--- /dev/null
+++ b/devel_generate/lib/Drupal/devel_generate/DevelGeneratePluginManager.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\devel_generate\DevelGeneratePluginManager.
+ */
+
+namespace Drupal\devel_generate;
+
+use \Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Plugin type manager for DevelGenerate plugins.
+ */
+Class DevelGeneratePluginManager extends DefaultPluginManager
+{
+
+  public function __construct(\Traversable $namespaces) {
+
+    parent::__construct('Plugin/DevelGenerate', $namespaces, 'Drupal\devel_generate\Annotation\DevelGenerate');
+
+    //$this->setCacheBackend($cache_backend, $language_manager, 'devel_generate_plugins');
+    //$this->alterInfo($module_handler, 'devel_generate_info');
+    $this->factory = new DevelGenerateFactory($this);
+
+  }
+
+}
\ No newline at end of file
diff --git a/devel_generate/lib/Drupal/devel_generate/Form/GenerateContent.php b/devel_generate/lib/Drupal/devel_generate/Form/GenerateContent.php
deleted file mode 100644
index 6e89c3a..0000000
--- a/devel_generate/lib/Drupal/devel_generate/Form/GenerateContent.php
+++ /dev/null
@@ -1,180 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\devel_generate\Form\GenerateContent.
- */
-
-namespace Drupal\devel_generate\Form;
-
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormInterface;
-use Drupal\Core\Language\Language;
-
-/**
- * Defines a form that allows privileged users to generate nodes and comments.
- */
-class GenerateContent extends FormBase implements FormInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormID() {
-    return 'devel_generate_content_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, array &$form_state) {
-    $form = array(
-      '#title' => t('Generate content'),
-      '#description' => t('Generate a given number of nodes and comments. Optionally delete current items.'),
-    );
-
-    $options = array();
-
-    if (module_exists('content')) {
-      $types = content_types();
-      foreach ($types as $type) {
-        $warn = '';
-        if (count($type['fields'])) {
-          $warn = t('. This type contains CCK fields which will only be populated by fields that implement the content_generate hook.');
-        }
-        $options[$type['type']] = array('#markup' => t($type['name']). $warn);
-      }
-    }
-    else {
-      $types = node_type_get_types();
-      foreach ($types as $type) {
-        $options[$type->type] = array(
-          'type' => array('#markup' => t($type->name)),
-        );
-        if (module_exists('comment')) {
-          $default = variable_get('comment_' . $type->type, COMMENT_OPEN);
-          $map = array(t('Hidden'), t('Closed'), t('Open'));
-          $options[$type->type]['comments'] = array('#markup' => '<small>'. $map[$default]. '</small>');
-        }
-      }
-    }
-    // we cannot currently generate valid polls.
-    unset($options['poll']);
-
-    if (empty($options)) {
-      drupal_set_message(t('You do not have any content types that can be generated. <a href="@create-type">Go create a new content type</a> already!</a>', array('@create-type' => url('admin/structure/types/add'))), 'error', FALSE);
-      return;
-    }
-
-    $header = array(
-      'type' => t('Content type'),
-    );
-    if (module_exists('comment')) {
-      $header['comments'] = t('Comments');
-    }
-
-    $form['node_types'] = array(
-      '#type' => 'table',
-      '#header' => $header,
-      '#tableselect' => TRUE,
-    );
-
-    $form['node_types'] += $options;
-
-    if (module_exists('checkall')) $form['node_types']['#checkall'] = TRUE;
-    $form['kill_content'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('<strong>Delete all content</strong> in these content types before generating new content.'),
-      '#default_value' => FALSE,
-    );
-    $form['num_nodes'] = array(
-      '#type' => 'textfield',
-      '#title' => t('How many nodes would you like to generate?'),
-      '#default_value' => 50,
-      '#size' => 10,
-    );
-
-    $options = array(1 => t('Now'));
-    foreach (array(3600, 86400, 604800, 2592000, 31536000) as $interval) {
-      $options[$interval] = format_interval($interval, 1) . ' ' . t('ago');
-    }
-    $form['time_range'] = array(
-      '#type' => 'select',
-      '#title' => t('How far back in time should the nodes be dated?'),
-      '#description' => t('Node creation dates will be distributed randomly from the current time, back to the selected time.'),
-      '#options' => $options,
-      '#default_value' => 604800,
-    );
-
-    $form['max_comments'] = array(
-      '#type' => module_exists('comment') ? 'textfield' : 'value',
-      '#title' => t('Maximum number of comments per node.'),
-      '#description' => t('You must also enable comments for the content types you are generating. Note that some nodes will randomly receive zero comments. Some will receive the max.'),
-      '#default_value' => 0,
-      '#size' => 3,
-      '#access' => module_exists('comment'),
-    );
-    $form['title_length'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Maximum number of words in titles'),
-      '#default_value' => 4,
-      '#size' => 10,
-    );
-    $form['add_alias'] = array(
-      '#type' => 'checkbox',
-      '#disabled' => !module_exists('path'),
-      '#description' => t('Requires path.module'),
-      '#title' => t('Add an url alias for each node.'),
-      '#default_value' => FALSE,
-    );
-    $form['add_statistics'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Add statistics for each node (node_counter table).'),
-      '#default_value' => TRUE,
-      '#access' => module_exists('statistics'),
-    );
-
-    unset($options);
-    $options[Language::LANGCODE_NOT_SPECIFIED] = t('Language neutral');
-    if (module_exists('locale')) {
-      $languages = language_list();
-      foreach ($languages as $langcode => $language) {
-        $options[$langcode] = $language->name;
-      }
-    }
-    $form['add_language'] = array(
-      '#type' => 'select',
-      '#title' => t('Set language on nodes'),
-      '#multiple' => TRUE,
-      '#disabled' => !module_exists('locale'),
-      '#description' => t('Requires locale.module'),
-      '#options' => $options,
-      '#default_value' => array(Language::LANGCODE_NOT_SPECIFIED),
-    );
-
-    $form['submit'] = array(
-      '#type' => 'submit',
-      '#value' => t('Generate'),
-      '#tableselect' => TRUE,
-    );
-    $form['#redirect'] = FALSE;
-
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, array &$form_state) {
-    module_load_include('inc', 'devel_generate', 'devel_generate');
-    if ($form_state['values']['num_nodes'] <= 50 && $form_state['values']['max_comments'] <= 10) {
-      module_load_include('inc', 'devel_generate');
-      devel_generate_content($form_state);
-    }
-    else {
-      module_load_include('inc', 'devel_generate', 'devel_generate_batch');
-      devel_generate_batch_content($form_state);
-    }
-  }
-
-}
diff --git a/devel_generate/lib/Drupal/devel_generate/Form/GenerateForm.php b/devel_generate/lib/Drupal/devel_generate/Form/GenerateForm.php
new file mode 100755
index 0000000..be24d7d
--- /dev/null
+++ b/devel_generate/lib/Drupal/devel_generate/Form/GenerateForm.php
@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\devel_generate\Form\GenerateForm.
+ */
+
+namespace Drupal\devel_generate\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormInterface;
+
+/**
+ * Defines a form that allows privileged users to generate entities.
+ */
+class GenerateForm extends FormBase implements FormInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'devel_generate_form';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+
+    $devel_generate_manager = \Drupal::service('plugin.manager.develgenerate');
+    $element_to_generate = arg(4);
+    $instance = $devel_generate_manager->createInstance($element_to_generate, array());
+
+    $form = $instance->settingsForm($form, $form_state);
+    $form_state['instance'] = $instance;
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => t('Generate'),
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {
+
+    $values = $form_state['values'];
+    $instance = $form_state['instance'];
+    $instance->generate($values);
+  }
+
+}
diff --git a/devel_generate/lib/Drupal/devel_generate/Form/GenerateMenu.php b/devel_generate/lib/Drupal/devel_generate/Form/GenerateMenu.php
deleted file mode 100644
index 40c3a76..0000000
--- a/devel_generate/lib/Drupal/devel_generate/Form/GenerateMenu.php
+++ /dev/null
@@ -1,147 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\devel_generate\Form\GenerateMenu.
- */
-
-namespace Drupal\devel_generate\Form;
-
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormInterface;
-
-/**
- * Defines a form that allows privileged users to generate menus and menu links.
- */
-class GenerateMenu extends FormBase implements FormInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormID() {
-    return 'devel_generate_menu_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, array &$form_state) {
-    $form = array(
-      '#title' => $this->t('Generate menus'),
-      '#description' => $this->t('Generate a given number of menus and menu links. Optionally delete current menus.'),
-    );
-
-    $menu_enabled = module_exists('menu');
-    if ($menu_enabled) {
-      $menus = array('__new-menu__' => t('Create new menu(s)')) + menu_get_menus();
-    }
-    else {
-      $menus = menu_list_system_menus();
-    }
-    $form['existing_menus'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Generate links for these menus'),
-      '#options' => $menus,
-      '#default_value' => array('__new-menu__'),
-      '#required' => TRUE,
-    );
-    if ($menu_enabled) {
-      $form['num_menus'] = array(
-        '#type' => 'textfield',
-        '#title' => t('Number of new menus to create'),
-        '#default_value' => 2,
-        '#size' => 10,
-        '#states' => array(
-          'visible' => array(
-            ':input[name=existing_menus[__new-menu__]]' => array('checked' => TRUE),
-          ),
-        ),
-      );
-    }
-    $form['num_links'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Number of links to generate'),
-      '#default_value' => 50,
-      '#size' => 10,
-      '#required' => TRUE,
-    );
-    $form['title_length'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Maximum number of characters in menu and menu link names'),
-      '#description' => t("The minimum length is 2."),
-      '#default_value' => 12,
-      '#size' => 10,
-      '#required' => TRUE,
-    );
-    $form['link_types'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Types of links to generate'),
-      '#options' => array(
-        'node' => t('Nodes'),
-        'front' => t('Front page'),
-        'external' => t('External'),
-      ),
-      '#default_value' => array('node', 'front', 'external'),
-      '#required' => TRUE,
-    );
-    $form['max_depth'] = array(
-      '#type' => 'select',
-      '#title' => t('Maximum link depth'),
-      '#options' => range(0, MENU_MAX_DEPTH),
-      '#default_value' => floor(MENU_MAX_DEPTH / 2),
-      '#required' => TRUE,
-    );
-    unset($form['max_depth']['#options'][0]);
-    $form['max_width'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Maximum menu width'),
-      '#default_value' => 6,
-      '#size' => 10,
-      '#description' => t("Limit the width of the generated menu's first level of links to a certain number of items."),
-      '#required' => TRUE,
-    );
-    $form['kill'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Delete existing custom generated menus and menu links before generating new ones.'),
-      '#default_value' => FALSE,
-    );
-    $form['submit'] = array(
-      '#type' => 'submit',
-      '#value' => t('Generate'),
-    );
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, array &$form_state) {
-    // If the create new menus checkbox is off, set the number of new menus to 0.
-    if (!isset($form_state['values']['existing_menus']['__new-menu__']) || !$form_state['values']['existing_menus']['__new-menu__']) {
-      $form_state['values']['num_menus'] = 0;
-    }
-    else {
-      // Unset the aux menu to avoid attach menu new items.
-      unset($form_state['values']['existing_menus']['__new-menu__']);
-    }
-    module_load_include('inc', 'devel_generate');
-    // Delete custom menus.
-    if ($form_state['values']['kill']) {
-      devel_generate_delete_menus();
-      drupal_set_message(t('Deleted existing menus and links.'));
-    }
-
-    // Generate new menus.
-    $new_menus = devel_generate_menus($form_state['values']['num_menus'], $form_state['values']['title_length']);
-    if (!empty($new_menus)) {
-      drupal_set_message(t('Created the following new menus: !menus', array('!menus' => implode(', ', $new_menus))));
-    }
-
-    // Generate new menu links.
-    $menus = $new_menus + $form_state['values']['existing_menus'];
-    $new_links = devel_generate_links($form_state['values']['num_links'], $menus, $form_state['values']['title_length'], $form_state['values']['link_types'], $form_state['values']['max_depth'], $form_state['values']['max_width']);
-    drupal_set_message(t('Created @count new menu links.', array('@count' => count($new_links))));
-  }
-
-}
diff --git a/devel_generate/lib/Drupal/devel_generate/Form/GenerateTerm.php b/devel_generate/lib/Drupal/devel_generate/Form/GenerateTerm.php
deleted file mode 100644
index d2401a8..0000000
--- a/devel_generate/lib/Drupal/devel_generate/Form/GenerateTerm.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\devel_generate\Form\GenerateTerm.
- */
-
-namespace Drupal\devel_generate\Form;
-
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormInterface;
-
-/**
- * Defines a form that allows privileged users to generate terms.
- */
-class GenerateTerm extends FormBase implements FormInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormID() {
-    return 'devel_generate_term_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, array &$form_state) {
-    $form = array(
-      '#title' => t('Generate terms'),
-      '#description' => t('Generate a given number of terms. Optionally delete current terms.'),
-    );
-
-    $options = array();
-    foreach (entity_load_multiple('taxonomy_vocabulary') as $vid => $vocab) {
-      $options[$vid] = $vocab->vid;
-    }
-    $form['vids'] = array(
-      '#type' => 'select',
-      '#multiple' => TRUE,
-      '#title' => t('Vocabularies'),
-      '#required' => TRUE,
-      '#options' => $options,
-      '#description' => t('Restrict terms to these vocabularies.'),
-    );
-    $form['num_terms'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Number of terms?'),
-      '#default_value' => 10,
-      '#size' => 10,
-    );
-    $form['title_length'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Maximum number of characters in term names'),
-      '#default_value' => 12,
-      '#size' => 10,
-    );
-    $form['kill_taxonomy'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Delete existing terms in specified vocabularies before generating new terms.'),
-      '#default_value' => FALSE,
-    );
-    $form['submit'] = array(
-      '#type' => 'submit',
-      '#value' => t('Generate'),
-    );
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, array &$form_state) {
-    $values = $form_state['values'];
-    module_load_include('inc', 'devel_generate');
-    if ($values['kill_taxonomy']) {
-      foreach ($values['vids'] as $vid) {
-        devel_generate_delete_vocabulary_terms($vid);
-      }
-      drupal_set_message(t('Deleted existing terms.'));
-    }
-    $vocabs = entity_load_multiple('taxonomy_vocabulary', $values['vids']);
-    $new_terms = devel_generate_terms($values['num_terms'], $vocabs, $values['title_length']);
-    if (!empty($new_terms)) {
-      drupal_set_message(t('Created the following new terms: !terms', array('!terms' => implode(', ', $new_terms))));
-    }
-  }
-
-}
diff --git a/devel_generate/lib/Drupal/devel_generate/Form/GenerateUser.php b/devel_generate/lib/Drupal/devel_generate/Form/GenerateUser.php
deleted file mode 100644
index 849e70d..0000000
--- a/devel_generate/lib/Drupal/devel_generate/Form/GenerateUser.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\devel_generate\Form\GenerateUser.
- */
-
-namespace Drupal\devel_generate\Form;
-
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormInterface;
-
-/**
- * Defines a form that allows privileged users to generate users.
- */
-class GenerateUser extends FormBase implements FormInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormID() {
-    return 'devel_generate_users_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, array &$form_state) {
-    $form = array(
-      '#title' => $this->t('Generate users'),
-      '#description' => $this->t('Generate a given number of users. Optionally delete current users.'),
-    );
-
-    $form['num'] = array(
-      '#type' => 'textfield',
-      '#title' => t('How many users would you like to generate?'),
-      '#default_value' => 50,
-      '#size' => 10,
-    );
-    $form['kill_users'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Delete all users (except user id 1) before generating new users.'),
-      '#default_value' => FALSE,
-    );
-    $options = user_role_names(TRUE);
-    unset($options[DRUPAL_AUTHENTICATED_RID]);
-    $form['roles'] = array(
-      '#type' => 'checkboxes',
-      '#title' => t('Which roles should the users receive?'),
-      '#description' => t('Users always receive the <em>authenticated user</em> role.'),
-      '#options' => $options,
-    );
-    $form['pass'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Password to be set'),
-      '#default_value' => NULL,
-      '#size' => 32,
-      '#description' => t('Leave this field empty if you do not need to set a password'),
-    );
-
-    $options = array(1 => t('Now'));
-    foreach (array(3600, 86400, 604800, 2592000, 31536000) as $interval) {
-      $options[$interval] = format_interval($interval, 1) . ' ' . t('ago');
-    }
-    $form['time_range'] = array(
-      '#type' => 'select',
-      '#title' => t('How old should user accounts be?'),
-      '#description' => t('User ages will be distributed randomly from the current time, back to the selected time.'),
-      '#options' => $options,
-      '#default_value' => 604800,
-    );
-
-    $form['submit'] = array(
-      '#type' => 'submit',
-      '#value' => t('Generate'),
-    );
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, array &$form_state) {
-    module_load_include('inc', 'devel_generate');
-    $values = $form_state['values'];
-    devel_create_users($values['num'], $values['kill_users'], $values['time_range'], $values['roles'], $values['pass']);
-  }
-
-}
diff --git a/devel_generate/lib/Drupal/devel_generate/Form/GenerateVocabulary.php b/devel_generate/lib/Drupal/devel_generate/Form/GenerateVocabulary.php
deleted file mode 100644
index c164df8..0000000
--- a/devel_generate/lib/Drupal/devel_generate/Form/GenerateVocabulary.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains \Drupal\devel_generate\Form\GenerateVocabulary.
- */
-
-namespace Drupal\devel_generate\Form;
-
-use Drupal\Core\Form\FormBase;
-use Drupal\Core\Form\FormInterface;
-
-/**
- * Defines a form that allows privileged users to generate vocabularies.
- */
-class GenerateVocabulary extends FormBase implements FormInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormID() {
-    return 'devel_generate_vocab_form';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, array &$form_state) {
-    $form = array(
-      '#title' => t('Generate vocabularies'),
-      '#description' => t('Generate a given number of vocabularies. Optionally delete current vocabularies.'),
-    );
-
-    $form['num_vocabs'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Number of vocabularies?'),
-      '#default_value' => 1,
-      '#size' => 10,
-    );
-    $form['title_length'] = array(
-      '#type' => 'textfield',
-      '#title' => t('Maximum number of characters in vocabulary names'),
-      '#default_value' => 12,
-      '#size' => 10,
-    );
-    $form['kill_taxonomy'] = array(
-      '#type' => 'checkbox',
-      '#title' => t('Delete existing vocabularies before generating new ones.'),
-      '#default_value' => FALSE,
-    );
-    $form['submit'] = array(
-      '#type' => 'submit',
-      '#value' => t('Generate'),
-    );
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, array &$form_state) {
-    $values = $form_state['values'];
-    module_load_include('inc', 'devel_generate');
-    if ($values['kill_taxonomy']) {
-      devel_generate_delete_vocabularies();
-      drupal_set_message(t('Deleted existing vocabularies.'));
-    }
-    $new_vocs = devel_generate_vocabs($values['num_vocabs'], $values['title_length']);
-    if (!empty($new_vocs)) {
-      drupal_set_message(t('Created the following new vocabularies: !vocs', array('!vocs' => implode(', ', $new_vocs))));
-    }
-  }
-
-}
diff --git a/devel_generate/lib/Drupal/devel_generate/Plugin/DevelGenerate/UserDevelGenerate.php b/devel_generate/lib/Drupal/devel_generate/Plugin/DevelGenerate/UserDevelGenerate.php
new file mode 100755
index 0000000..3e7fedc
--- /dev/null
+++ b/devel_generate/lib/Drupal/devel_generate/Plugin/DevelGenerate/UserDevelGenerate.php
@@ -0,0 +1,180 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\devel_generate\Plugin\DevelGenerate\UserDevelGenerate.
+ */
+
+namespace Drupal\devel_generate\Plugin\DevelGenerate;
+
+use Drupal\devel_generate\DevelGenerateBase;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a UserDevelGenerate plugin.
+ *
+ * @DevelGenerate(
+ *   id = "user",
+ *   settings = {
+ *     "num" = 53,
+ *     "kill_users" = FALSE,
+ *     "pass" = ""
+ *   },
+ *   drushSettings = {
+ *     "suffix" = "users",
+ *     "alias" = "u",
+ *     "num" = "Number of user to be created",
+ *     "kill" = "Delete existing users",
+ *     "pass" = "Set a predifined password",
+ *     "roles" = "Roles for new users"
+ *   },
+ *   drushArgs= {
+ *     "num" = "Number of users to create",
+ *   }
+ * )
+ */
+class UserDevelGenerate extends DevelGenerateBase implements ContainerFactoryPluginInterface {
+
+  private function generateWord($length) {
+    mt_srand((double)microtime()*1000000);
+
+    $vowels = array("a", "e", "i", "o", "u");
+    $cons = array("b", "c", "d", "g", "h", "j", "k", "l", "m", "n", "p", "r", "s", "t", "u", "v", "w", "tr",
+      "cr", "br", "fr", "th", "dr", "ch", "ph", "wr", "st", "sp", "sw", "pr", "sl", "cl", "sh");
+
+    $num_vowels = count($vowels);
+    $num_cons = count($cons);
+    $word = '';
+
+    while(strlen($word) < $length){
+      $word .= $cons[mt_rand(0, $num_cons - 1)] . $vowels[mt_rand(0, $num_vowels - 1)];
+    }
+
+    return substr($word, 0, $length);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) {
+    return new static(
+      //@todo: implement create method.
+    );
+  }
+
+  public function settingsForm(array $form, array &$form_state) {
+
+    $form['num'] = array(
+      '#type' => 'textfield',
+      '#title' => t('How many users would you like to generate?'),
+      '#default_value' => $this->getSetting('num'),
+      '#size' => 10,
+    );
+
+    $form['kill_users'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Delete all users (except user id 1) before generating new users.'),
+      '#default_value' => $this->getSetting('kill_users'),
+    );
+
+    $options = user_role_names(TRUE);
+    unset($options[DRUPAL_AUTHENTICATED_RID]);
+    $form['roles'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Which roles should the users receive?'),
+      '#description' => t('Users always receive the <em>authenticated user</em> role.'),
+      '#options' => $options,
+    );
+
+    $form['pass'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Password to be set'),
+      '#default_value' => $this->getSetting('pass'),
+      '#size' => 32,
+      '#description' => t('Leave this field empty if you do not need to set a password'),
+    );
+
+    $options = array(1 => t('Now'));
+    foreach (array(3600, 86400, 604800, 2592000, 31536000) as $interval) {
+      $options[$interval] = format_interval($interval, 1) . ' ' . t('ago');
+    }
+    $form['time_range'] = array(
+      '#type' => 'select',
+      '#title' => t('How old should user accounts be?'),
+      '#description' => t('User ages will be distributed randomly from the current time, back to the selected time.'),
+      '#options' => $options,
+      '#default_value' => 604800,
+    );
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function generateElements(array $values) {
+    $num = $values['num'];
+    $kill = $values['kill_users'];
+    $pass = $values['pass'];
+    $age = $values['time_range'];
+    $roles = $values['roles'];
+    $url = parse_url($GLOBALS['base_url']);
+    if ($kill) {
+      $uids = db_select('users', 'u')
+        ->fields('u', array('uid'))
+        ->condition('uid', 1, '>')
+        ->execute()
+        ->fetchAllAssoc('uid');
+      user_delete_multiple(array_keys($uids));
+      drupal_set_message(format_plural(count($uids), '1 user deleted', '@count users deleted.'));
+    }
+
+    if ($num > 0) {
+      $names = array();
+      while (count($names) < $num) {
+        //@todo add suport for devel_generate_word(mt_rand(6, 12)) in a class method
+        $name = $this->generateWord(mt_rand(6, 12));
+        $names[$name] = '';
+      }
+
+      if (empty($roles)) {
+        $roles = array(DRUPAL_AUTHENTICATED_RID);
+      }
+      foreach ($names as $name => $value) {
+        $edit = array(
+          'uid'     => NULL,
+          'name'    => $name,
+          'pass'    => $pass,
+          'mail'    => $name . '@' . $url['host'] . '.invalid',
+          'status'  => 1,
+          'created' => REQUEST_TIME - mt_rand(0, $age),
+          'roles' => drupal_map_assoc($roles),
+          'devel_generate' => TRUE // A flag to let hook_user_* know that this is a generated user.
+        );
+        $account = entity_create('user', $edit);
+
+        // Populate all core fields on behalf of field.module
+        module_load_include('inc', 'devel_generate', 'devel_generate.fields');
+        devel_generate_fields($account, 'user', 'user', 'register');
+        $account->save();
+      }
+    }
+    drupal_set_message(t('!num_users created.', array('!num_users' => format_plural($num, '1 user', '@count users'))));
+  }
+
+  public function getDrushValues($args) {
+    $values = array(
+      'num' => array_shift($args),
+      'roles' => drush_get_option('roles') ? explode(',', drush_get_option('roles')) : array(),
+      'kill_users' => drush_get_option('kill'),
+      'pass' => drush_get_option('pass', NULL),
+      'time_range' => 0,
+    );
+    return $values;
+  }
+
+  public function drushLog($values = array()) {
+    drush_log(t('Generated @number users.', array('@number' => $values['num'])), 'success');
+  }
+
+}
diff --git a/devel_generate/lib/Drupal/devel_generate/Routing/DevelGenerateRouteSubscriber.php b/devel_generate/lib/Drupal/devel_generate/Routing/DevelGenerateRouteSubscriber.php
new file mode 100755
index 0000000..2a9182b
--- /dev/null
+++ b/devel_generate/lib/Drupal/devel_generate/Routing/DevelGenerateRouteSubscriber.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Definition of \Drupal\devel_generate\Routing\DevelGenerateRouteSubscriber.
+ */
+namespace Drupal\devel_generate\Routing;
+
+use Drupal\Core\Routing\RouteSubscriberBase;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
+
+/**
+ * Listens to the dynamic route event and add devel_generate route.
+ */
+class DevelGenerateRouteSubscriber extends RouteSubscriberBase {
+
+  public function routes(RouteCollection $collection) {
+
+    $devel_generate_plugins = $devel_generate_manager = \Drupal::service('plugin.manager.develgenerate')->getDefinitions();
+
+    foreach ($devel_generate_plugins as $id => $plugin) {
+      $type_url_str = str_replace('_', '-', $id);
+      $route = new Route(
+        'admin/config/development/generate/' . $type_url_str,
+        array(
+          '_form' => '\Drupal\devel_generate\Form\GenerateForm',
+          '_title' => 'Generate',
+        ),
+        array(
+          '_permission' => 'admin devel generate',
+        )
+      );
+      $collection->add('devel_generate.' . $id, $route);
+    }
+  }
+}
diff --git a/devel_generate/lib/Drupal/devel_generate/Tests/DevelGenerateTest.php b/devel_generate/lib/Drupal/devel_generate/Tests/DevelGenerateTest.php
old mode 100644
new mode 100755
diff --git a/devel_generate/link.devel_generate.inc b/devel_generate/link.devel_generate.inc
deleted file mode 100644
index 4414c31..0000000
--- a/devel_generate/link.devel_generate.inc
+++ /dev/null
@@ -1,50 +0,0 @@
-<?php
-/**
- * @file
- * Support file for generating link field content.
- */
-
-function link_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  if (isset($plugin_definition['multiple_values']) && $plugin_definition['multiple_values'] === TRUE) {
-    return devel_generate_multiple('_link_devel_generate', $object, $instance, $plugin_definition, $form_display_options);
-  }
-  else {
-    return _link_devel_generate($object, $instance, $plugin_definition, $form_display_options);
-  }
-}
-
-function _link_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  $object_field = array();
-  $settings = $instance->getFieldSettings();
-
-  // Set of possible top-level domains.
-  $tlds = array('com', 'net', 'gov', 'org', 'edu', 'biz', 'info');
-
-  // Set random length for the domain name.
-  $domain_length = mt_rand(7, 15);
-
-  // Get the title settings from the field instance.
-  $allow_title = $settings['title'];
-  switch ($allow_title) {
-    case DRUPAL_DISABLED:
-      $generate_title = FALSE;
-      break;
-    case DRUPAL_REQUIRED:
-      $generate_title = TRUE;
-      break;
-    case DRUPAL_OPTIONAL:
-      // In case of optional title, randomize its generation.
-      $generate_title = mt_rand(0,1);
-      break;
-  }
-
-  // Set the title value as the presave function is expecting it but only
-  // input content if needed.
-  $object_field['title'] = '';
-  if ($generate_title == TRUE) {
-    $object_field['title'] = devel_create_greeking(4);
-  }
-
-  $object_field['url'] = 'http://www.' . devel_generate_word($domain_length) . '.' . $tlds[mt_rand(0, (sizeof($tlds)-1))];
-  return $object_field;
-}
diff --git a/devel_generate/number.devel_generate.inc b/devel_generate/number.devel_generate.inc
deleted file mode 100644
index 9d2d6a8..0000000
--- a/devel_generate/number.devel_generate.inc
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-// Id$
-
-function number_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  if (isset($plugin_definition['multiple_values']) && $plugin_definition['multiple_values'] === TRUE) {
-    return devel_generate_multiple('_number_devel_generate', $object, $instance, $plugin_definition, $form_display_options);
-  }
-  else {
-    return _number_devel_generate($object, $instance, $plugin_definition, $form_display_options);
-  }
-}
-
-function _number_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  $object_field = array();
-  $settings = $instance->getFieldSettings();
-
-  // Make sure the instance settings are all set.
-  foreach (array('min', 'max', 'precision', 'scale') as $key) {
-    if (empty($settings[$key])) {
-      $settings[$key] = NULL;
-    }
-  }
-  $min = is_numeric($settings['min']) ? $settings['min'] : 0;
-  switch ($form_display_options['type']) {
-    case 'number_integer':
-      $max = is_numeric($settings['max']) ? $settings['max'] : 10000;
-      $decimal = 0;
-      $scale = 0;
-      break;
-
-    case 'number_decimal':
-      $precision = is_numeric($settings['precision']) ? $settings['precision'] : 10;
-      $scale = is_numeric($settings['scale']) ? $settings['scale'] : 2;
-      $max = is_numeric($settings['max']) ? $settings['max'] : pow(10, ($precision - $scale));
-      $decimal = rand(0, (10 * $scale)) / 100;
-      break;
-
-    case 'number_float':
-      $precision = rand(10, 32);
-      $scale = rand(0, 2);
-      $decimal = rand(0, (10 * $scale)) / 100;
-      $max = is_numeric($settings['max']) ? $settings['max'] : pow(10, ($precision - $scale));
-      break;
-  }
-  $object_field['value'] = round((rand($min, $max) + $decimal), $scale);
-  return $object_field;
-}
diff --git a/devel_generate/options.devel_generate.inc b/devel_generate/options.devel_generate.inc
deleted file mode 100644
index aa42fd5..0000000
--- a/devel_generate/options.devel_generate.inc
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-use Drupal\field\Field;
-
-function options_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  if (isset($plugin_definition['multiple_values']) && $plugin_definition['multiple_values'] === TRUE) {
-    return devel_generate_multiple('_options_devel_generate', $object, $instance, $plugin_definition, $form_display_options);
-  }
-  else {
-    return _options_devel_generate($object, $instance, $plugin_definition, $form_display_options);
-  }
-}
-
-function _options_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  $object_field = array();
-  $field_info = Field::fieldInfo()->getField($object->entityType(), $instance->getFieldName());
-  if ($allowed_values = options_allowed_values($field_info, $object)) {
-    $keys = array_keys($allowed_values);
-    $object_field['value'] = $keys[mt_rand(0, count($allowed_values) - 1)];
-  }
-  return $object_field;
-}
diff --git a/devel_generate/taxonomy.devel_generate.inc b/devel_generate/taxonomy.devel_generate.inc
deleted file mode 100644
index e0ca3fd..0000000
--- a/devel_generate/taxonomy.devel_generate.inc
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-function taxonomy_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  if (isset($plugin_definition['multiple_values']) && $plugin_definition['multiple_values'] === TRUE) {
-    return devel_generate_multiple('_taxonomy_devel_generate', $object, $instance, $plugin_definition, $form_display_options);
-  }
-  else {
-    return _taxonomy_devel_generate($object, $instance, $plugin_definition, $form_display_options);
-  }
-}
-
-function _taxonomy_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  $object_field = array();
-  $settings = $instance->getFieldSettings();
-  // TODO: For free tagging vocabularies that do not already have terms, this
-  // will not result in any tags being added.
-  $machine_name = $settings['allowed_values'][0]['vocabulary'];
-  $vocabulary = entity_load('taxonomy_vocabulary', $machine_name);
-  if ($max = db_query('SELECT MAX(tid) FROM {taxonomy_term_data} WHERE vid = :vid', array(':vid' => $vocabulary->vid))->fetchField()) {
-    $candidate = mt_rand(1, $max);
-    $query = db_select('taxonomy_term_data', 't');
-    $tid = $query
-              ->fields('t', array('tid'))
-              ->condition('t.vid', $vocabulary->vid, '=')
-              ->condition('t.tid', $candidate, '>=')
-              ->range(0,1)
-              ->execute()
-              ->fetchField();
-    // If there are no terms for the taxonomy, the query will fail, in which
-    // case we return NULL.
-    if ($tid === FALSE) {
-      return NULL;
-    }
-    $object_field['target_id'] = (int) $tid;
-    return $object_field;
-  }
-}
diff --git a/devel_generate/text.devel_generate.inc b/devel_generate/text.devel_generate.inc
deleted file mode 100644
index 9c62ee2..0000000
--- a/devel_generate/text.devel_generate.inc
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-function text_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  if (isset($plugin_definition['multiple_values']) && $plugin_definition['multiple_values'] === TRUE) {
-    return devel_generate_multiple('_text_devel_generate', $object, $instance, $plugin_definition, $form_display_options);
-  }
-  else {
-    return _text_devel_generate($object, $instance, $plugin_definition, $form_display_options);
-  }
-}
-
-function _text_devel_generate($object, $instance, $plugin_definition, $form_display_options) {
-  $object_field = array();
-  $settings = $instance->getFieldSettings();
-  if (!empty($settings['text_processing'])) {
-    $formats = filter_formats();
-    $format = array_rand($formats);
-  }
-  else {
-    $format = filter_fallback_format();
-  }
-
-  if (empty($settings['max_length'])) {
-    // Textarea handling
-    $object_field['value'] = devel_create_content($format);
-    if ($form_display_options['type'] == 'text_textarea_with_summary' && !empty($settings['display_summary'])) {
-      $object_field['summary'] = devel_create_content($format);
-    }
-  }
-  else {
-    // Textfield handling.
-    $object_field['value'] = substr(devel_create_greeking(mt_rand(1, $settings['max_length'] / 6), FALSE), 0, $settings['max_length']);
-  }
-  $object_field['format'] = $format;
-  return $object_field;
-}
