lib/plugins/create/create.js/Create/create
class Create:  create() {
    this.serverless.cli.log('Generating boilerplate...');
    const notPlugin = this.options.template !== 'plugin';

    if (validTemplates.indexOf(this.options.template) === -1) {
      const errorMessage = [
        `Template "${this.options.template}" is not supported.`,
        ` Supported templates are: ${humanReadableTemplateList}.`,
      ].join('');
      throw new this.serverless.classes.Error(errorMessage);
    }

    // store the custom options for the service if given
    const boilerplatePath = _.toString(this.options.path);
    const serviceName = _.toString(this.options.name);
    const templateSrcDir = path.join(this.serverless.config.serverlessPath,
      'plugins', 'create', 'templates', this.options.template);

    // create (if not yet present) and chdir into the directory for the service
    if (boilerplatePath) {
      const newPath = path.join(process.cwd(), boilerplatePath);

      if (this.serverless.utils.dirExistsSync(newPath)) {
        const errorMessage = [
          `The directory "${newPath}" already exists, and serverless will not overwrite it. `,
          'Rename or move the directory and try again if you want serverless to create it"',
        ].join('');

        throw new this.serverless.classes.Error(errorMessage);
      }

      this.serverless.cli.log(`Generating boilerplate in "${newPath}"`);

      fse.mkdirsSync(newPath);
      process.chdir(newPath);
    } else {
      // ensure no template file already exists in cwd that we may overwrite
      const templateFullFilePaths = this.serverless.utils.walkDirSync(templateSrcDir);

      templateFullFilePaths.forEach(ffp => {
        const filename = path.basename(ffp);
        if (this.serverless.utils.fileExistsSync(path.join(process.cwd(), filename))) {
          const errorMessage = [
            `The file "${filename}" already exists, and serverless will not overwrite it. `,
            `Move the file and try again if you want serverless to write a new "${filename}"`,
          ].join('');

          throw new this.serverless.classes.Error(errorMessage);
        }
      });
    }

    if (notPlugin) {
      this.serverless.config.update({ servicePath: process.cwd() });
    }

    // copy template files recursively to cwd
    // while keeping template file tree
    try {
      this.serverless.utils.copyDirContentsSync(templateSrcDir, process.cwd());

      // NPM renames .gitignore to .npmignore on publish so we have to rename it.
      if (this.serverless.utils.fileExistsSync(`${process.cwd()}/gitignore`)) {
        fse.rename(`${process.cwd()}/gitignore`, `${process.cwd()}/.gitignore`);
      }
    } catch (err) {
      const errorMessage = [
        'Error unable to create a service in this directory. ',
        'Please check that you have the required permissions to write to the directory',
      ].join('');

      throw new this.serverless.classes.Error(errorMessage);
    }

    // rename the service if the user has provided a path via options and is creating a service
    if ((boilerplatePath || serviceName) && notPlugin) {
      const newServiceName = serviceName || boilerplatePath.split(path.sep).pop();
      const serverlessYmlFilePath = path
        .join(this.serverless.config.servicePath, 'serverless.yml');

      let serverlessYmlFileContent = fse
        .readFileSync(serverlessYmlFilePath).toString();

      serverlessYmlFileContent = serverlessYmlFileContent
        .replace(/service: .+/, `service: ${newServiceName}`);

      fse.writeFileSync(serverlessYmlFilePath, serverlessYmlFileContent);
    }

    userStats.track('service_created', {
      template: this.options.template,
      serviceName,
    });

    this.serverless.cli.asciiGreeting();
    this.serverless.cli
      .log(`Successfully generated boilerplate for template: "${this.options.template}"`);

    if (!(boilerplatePath || serviceName) && notPlugin) {
      this.serverless.cli
        .log('NOTE: Please update the "service" property in serverless.yml with your service name');
    }

    return BbPromise.resolve();
  }