diff --git a/.eslintrc.js b/.eslintrc.js
index fd6e0c605cc2b785fe8c8a85387b88072ed34af7..c2639598e11596273c44b3ed168384c4678ad6c1 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -39,7 +39,15 @@ module.exports = {
     'no-else-return': 'off',
 
     // allow dangling underscores for 'fields'
-    'no-underscore-dangle': ['error', {'allowAfterThis': true}],
+    'no-underscore-dangle': 'off',
+
+    // Allow marking variables unused using a underscore at the start
+    'no-unused-vars': ["error", {
+      "varsIgnorePattern": "^_.*$",
+      "argsIgnorePattern": "^_.*$",
+      "caughtErrorsIgnorePattern": "^_.*$"
+    }],
+
 
     // enforce license header (todo: improve plugin to support patterns for multi-lines)
     'header/header': [2, 'block', ['',
diff --git a/cli.js b/cli.js
index 6e0e776c8d3427a7607f8eb260f1dc6d95371907..60d5a0d638fc7159cb4aa91df31df2b40374bde8 100755
--- a/cli.js
+++ b/cli.js
@@ -11,6 +11,7 @@
  * governing permissions and limitations under the License.
  */
 
+const Optimist = require('optimist');
 const Promise = require('bluebird');
 const path = require('path');
 const _ = require('lodash');
@@ -18,12 +19,13 @@ const fs = Promise.promisifyAll(require('fs'));
 const readdirp = require('readdirp');
 const Ajv = require('ajv');
 const logger = require('winston');
+const i18n = require('i18n');
 
 const Schema = require('./lib/schema');
 const readSchemaFile = require('./lib/readSchemaFile');
 
 // parse/process command line arguments
-const { argv } = require('optimist')
+const { argv } = Optimist
   .usage('Generate Markdown documentation from JSON Schema.\n\nUsage: $0')
   .demand('d')
   .alias('d', 'input')
@@ -48,10 +50,10 @@ const { argv } = require('optimist')
   .describe('link-*', 'Add this file as a link the explain the * attribute, e.g. --link-abstract=abstract.md')
   .check((args) => {
     if (!fs.existsSync(args.input)) {
-      throw `Input file "${args.input}" does not exist!`;
+      throw new Error(`Input file "${args.input}" does not exist!`);
     }
     if (args.s && !fs.existsSync(args.s)) {
-      throw `Meta schema file "${args.s}" does not exist!`;
+      throw new Error(`Meta schema file "${args.s}" does not exist!`);
     }
   })
   .alias('i', 'i18n')
@@ -61,8 +63,11 @@ const { argv } = require('optimist')
   .default('h', true)
   .argv;
 
-const docs = _.fromPairs(_.toPairs(argv).filter(([key, value]) => key.startsWith('link-')).map(([key, value]) => [key.substr(5), value]));
-const i18n = require('i18n');
+const docs = _.fromPairs(
+  _.toPairs(argv)
+    .filter(([key, _value]) => key.startsWith('link-'))
+    .map(([key, value]) => [key.substr(5), value]),
+);
 
 logger.configure({
   level: 'info',
@@ -78,37 +83,41 @@ logger.configure({
 const ajv = new Ajv({
   allErrors: true, messages: true, schemaId: 'auto', logger,
 });
-console.log(argv.v);
+logger.info(argv.v);
 if (argv.v === '06' || argv.v === 6) {
-  console.log('enabling draft-06 support');
+  logger.info('enabling draft-06 support');
+  // eslint-disable-next-line global-require
   ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-06.json'));
 } else if (argv.v === '04' || argv.v === 4) {
+  // eslint-disable-next-line global-require
   ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));
 }
 const schemaPathMap = {};
 const metaElements = {};
 const schemaPath = path.resolve(argv.d);
 const outDir = path.resolve(argv.o);
-const schemaDir = argv.x === '-' ? '' : argv.x ? path.resolve(argv.x) : outDir;
+// eslint-disable-next-line no-nested-ternary
+const schemaDir = argv.x === '-' ? '' : (argv.x ? path.resolve(argv.x) : outDir);
 const target = fs.statSync(schemaPath);
 const readme = argv.n !== true;
 const schemaExtension = argv.e || 'schema.json';
 if (argv.s) {
+  // eslint-disable-next-line import/no-dynamic-require, global-require
   ajv.addMetaSchema(require(path.resolve(argv.s)));
 }
 
 if (argv.m) {
   if (_.isArray(argv.m)) {
     _.each(argv.m, (item) => {
-      const meta = item.split('=');
-      if (meta.length === 2) {
-        metaElements[meta[0]] = meta[1];
+      const [key, val] = item.split('=');
+      if (val !== undefined) {
+        metaElements[key] = val;
       }
     });
   } else {
-    const meta = (argv.m).split('=');
-    if (meta.length === 2) {
-      metaElements[meta[0]] = meta[1];
+    const [key, val] = (argv.m).split('=');
+    if (val !== undefined) {
+      metaElements[key] = val;
     }
   }
 }
@@ -134,6 +143,7 @@ if (target.isDirectory()) {
     .on('data', (entry) => {
       files.push(entry.fullPath);
       try {
+        // eslint-disable-next-line import/no-dynamic-require, global-require
         ajv.addSchema(require(entry.fullPath), entry.fullPath);
       } catch (e) {
         logger.error('Ajv processing error for schema at path %s', entry.fullPath);
@@ -146,8 +156,14 @@ if (target.isDirectory()) {
       Schema.setSchemaPathMap(schemaPathMap);
       return Promise.reduce(files, readSchemaFile, schemaPathMap)
         .then((schemaMap) => {
-          logger.info('finished reading all *.%s files in %s, beginning processing….', schemaExtension, schemaPath);
-          return Schema.process(schemaMap, schemaPath, outDir, schemaDir, metaElements, readme, docs, argv);
+          logger.info(
+            'finished reading all *.%s files in %s, beginning processing….',
+            schemaExtension, schemaPath,
+          );
+          return Schema.process(
+            schemaMap, schemaPath, outDir, schemaDir, metaElements,
+            readme, docs, argv,
+          );
         })
         .then(() => {
           logger.info('Processing complete.');
@@ -164,11 +180,13 @@ if (target.isDirectory()) {
 } else {
   readSchemaFile(schemaPathMap, schemaPath)
     .then((schemaMap) => {
+      // eslint-disable-next-line import/no-dynamic-require, global-require
       ajv.addSchema(require(schemaPath), schemaPath);
       Schema.setAjv(ajv);
       Schema.setSchemaPathMap(schemaPathMap);
       logger.info('finished reading %s, beginning processing....', schemaPath);
-      return Schema.process(schemaMap, schemaPath, outDir, schemaDir, metaElements, false, docs, argv);
+      return Schema.process(schemaMap, schemaPath, outDir, schemaDir,
+        metaElements, false, docs, argv);
     })
     .then(() => {
       logger.info('Processing complete.');
diff --git a/lib/header.js b/lib/header.js
index 693faf79ce663c4b61559a864b13f23d5a750511..dc5e255a0664bfeac095b86db927a2cbb55e9e71 100644
--- a/lib/header.js
+++ b/lib/header.js
@@ -16,7 +16,7 @@ const path = require('path');
 
 function custom(schema) {
   if (schema.allOf) {
-    for (let i = 0; i < schema.allOf.length; i++) {
+    for (let i = 0; i < schema.allOf.length; i += 1) {
       if (schema.allOf[i].$ref && schema.allOf[i].$ref === 'https://ns.adobe.com/xdm/common/extensible.schema.json#/definitions/@context') {
         return true;
       }
@@ -49,10 +49,10 @@ class Header {
     this.renderValue = this.render(this.value, this.links, this.base);
   }
 
-  render(text, link, base) {
-    return function () {
-      if (link) {
-        return `[${text}](${base}${link})`;
+  render(text, ref, base) {
+    return () => {
+      if (ref) {
+        return `[${text}](${base}${ref})`;
       } else {
         return text;
       }
@@ -67,14 +67,12 @@ function header(name, docs, value, links) {
   this.links = links;
 
 
-  this.render = function (text, link) {
-    return function () {
-      if (link) {
-        return `[${text}](${link})`;
-      } else {
-        return text;
-      }
-    };
+  this.render = (text, ref) => () => {
+    if (ref) {
+      return `[${text}](${ref})`;
+    } else {
+      return text;
+    }
   };
   this.renderHeader = this.render(this.name, this.docs);
   this.renderValue = this.render(this.value, this.links);
@@ -114,7 +112,7 @@ function headers(schema, indir, filename, docs) {
   this.myheaders.push(new Header(i18n.__('header.tabel.additionalProperties'), link(indir, filename, this.doclinks.additional), props.additionalProperties));
   this.myheaders.push(new Header(i18n.__('header.tabel.definedIn'), undefined, props.original, path.basename(props.original)));
 
-  this.render = function () {
+  this.render = () => {
     let buf = '';
 
     // header
diff --git a/lib/main.js b/lib/main.js
index e0559f21c0c401777a8c7c0fa606a8291dfba3ae..0e872309e8fdc32f64c4b7727f46352d729c0b2c 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -10,6 +10,8 @@
  * governing permissions and limitations under the License.
  */
 
+/* eslint-disable global-require */
+
 module.exports = {
   writer: require('./writeFiles'),
   reader: require('./readSchemaFile'),
diff --git a/lib/markdownWriter.js b/lib/markdownWriter.js
index 71f5c5b1902d97c71528ee0dee77c6b36c029102..87e0bbac71f2b7b3ba32cd4d5e0aafc4e72b075c 100644
--- a/lib/markdownWriter.js
+++ b/lib/markdownWriter.js
@@ -9,6 +9,9 @@
  * OF ANY KIND, either express or implied. See the License for the specific language
  * governing permissions and limitations under the License.
  */
+
+/* eslint-disable no-param-reassign */
+
 const i18n = require('i18n');
 const Promise = require('bluebird');
 const path = require('path');
@@ -16,7 +19,6 @@ const _ = require('lodash');
 const ejs = require('ejs');
 
 const pejs = Promise.promisifyAll(ejs);
-const validUrl = require('valid-url');
 const GithubSlugger = require('github-slugger');
 const { headers } = require('./header');
 const prettyMarkdown = require('./prettyMarkdown');
@@ -25,7 +27,7 @@ const writeFile = require('./writeFiles');
 function createGithubSlugs(names) {
   const slugger = new GithubSlugger();
   slugger.reset();
-  names = names.sort();
+  names = Array.from(names).sort();
   return names.reduce((result, item) => {
     result[item] = slugger.slug(item);
     return result;
@@ -41,7 +43,7 @@ function build(total, fragment) {
 }
 
 function assoc(obj, key, value) {
-  if (obj == null) {
+  if (obj === null) {
     return assoc({}, key, value);
   }
   obj[key] = value;
@@ -65,7 +67,6 @@ function stringifyExamples(examples) {
     if (typeof examples === 'string') {
       examples = [examples];
     }
-    // console.log(examples);
     return examples.map(example => JSON.stringify(example, null, 2));
   } else {
     return false;
@@ -82,6 +83,7 @@ function simpletype(prop) {
     if (prop.$linkVal !== undefined) {
       prop.simpletype = prop.$linkVal;
     } else {
+      // eslint-disable-next-line no-console
       console.log(`unresolved reference: ${prop.$ref}`);
       prop.simpletype = 'reference';
     }
@@ -90,7 +92,7 @@ function simpletype(prop) {
     if (prop['meta:enum'] === undefined) {
       prop['meta:enum'] = {};
     }
-    for (let i = 0; i < prop.enum.length; i++) {
+    for (let i = 0; i < prop.enum.length; i += 1) {
       if (prop['meta:enum'][prop.enum[i]] === undefined) {
         // setting an empty description for each unknown enum
         prop['meta:enum'][prop.enum[i]] = '';
@@ -116,22 +118,19 @@ function simpletype(prop) {
       if (innertype.simpletype === 'complex') {
         prop.simpletype = '`array`';
       } else {
-        // console.log(prop.title);
         prop.simpletype = innertype.simpletype.replace(/(`)$/, '[]$1');
       }
     } else {
       prop.simpletype = '`array`';
     }
   } else if (Array.isArray(type)) {
-    function nullfilter(str) {
-      return str !== 'null';
-    }
+    const nullfilter = str => str !== 'null';
     const filtered = type.filter(nullfilter);
     if (type.length - 1 === filtered.length) {
       prop.nullable = true;
     }
     if (filtered.length === 1) {
-      prop.type = filtered[0];
+      ([prop.type] = filtered);
       prop.simpletype = `\`${filtered[0]}\``;
     } else {
       prop.type = filtered;
@@ -151,9 +150,9 @@ function simpletype(prop) {
  */
 function requiredProperties(properties, required) {
   if (required) {
-    for (let i = 0; i < required.length; i++) {
-      if (properties[required[i]]) {
-        properties[required[i]].isrequired = true;
+    for (const prop of required) {
+      if (properties[prop]) {
+        properties[prop].isrequired = true;
       }
     }
   }
@@ -166,32 +165,35 @@ function ejsRender(template, ctx) {
   // return JSON.stringify(obj, null, 2);
 }
 
-const generateMarkdown = (filename, schema, schemaPath, outDir, dependencyMap, docs, consoleArgs) => {
+const generateMarkdown = (filename, schema, schemaPath, outDir,
+  dependencyMap, docs, consoleArgs) => {
   outDir = outDir || path.resolve(path.join('.', 'out'));
   // this structure allows us to have separate templates for each element. Instead of having
   // one huge template, each block can be built individually
-  outDir = outDir ? outDir : path.resolve(path.join('.', 'out'));
+  outDir = outDir || path.resolve(path.join('.', 'out'));
   let multi = [];
-  multi.push([ 'frontmatter.ejs', { meta: schema.metaElements } ]);
-  if (!consoleArgs||consoleArgs.header){
-    multi.push([ 'header.ejs', {
-      i18n: i18n,
-      schema: schema,
+  multi.push(['frontmatter.ejs', { meta: schema.metaElements }]);
+  if (!consoleArgs || consoleArgs.header) {
+    multi.push(['header.ejs', {
+      i18n,
+      schema,
       dependencies: flatten(dependencyMap),
-      table: headers(schema, schemaPath, filename, docs).render() } ]);
+      table: headers(schema, schemaPath, filename, docs).render(),
+    }]);
   }
-  multi.push([ 'examples.ejs', { examples: stringifyExamples(schema.examples), title: schema.title, i18n: i18n } ]);
-  const required = []; //to store required of whole schema, even those in definitions
+  multi.push(['examples.ejs', { examples: stringifyExamples(schema.examples), title: schema.title, i18n }]);
+  const required = []; // to store required of whole schema, even those in definitions
 
-  // Processing schema.definitions before schema.properties to get any required properties present in definitions
+  // Processing schema.definitions before schema.properties to get any
+  // required properties present in definitions
   if (_.keys(schema.definitions).length > 0) {
     const abstract = {};
-    for (let i = 0; i < _.keys(schema.definitions).length; i++) {
+    for (let i = 0; i < _.keys(schema.definitions).length; i += 1) {
       if (schema.definitions[_.keys(schema.definitions)[i]].properties !== undefined) {
         const definition = schema.definitions[_.keys(schema.definitions)[i]].properties;
         const tempRequired = schema.definitions[_.keys(schema.definitions)[i]].required;
         const hasRequiredProperties = (tempRequired !== undefined);
-        for (let j = 0; j < _.keys(definition).length; j++) {
+        for (let j = 0; j < _.keys(definition).length; j += 1) {
           const name = _.keys(definition)[j];
           const property = definition[_.keys(definition)[j]];
           if (hasRequiredProperties && tempRequired.includes(name)) {
@@ -215,7 +217,7 @@ const generateMarkdown = (filename, schema, schemaPath, outDir, dependencyMap, d
         propertiesSlugs,
         i18n,
       }]);
-      for (let i = 0; i < _.keys(abstract).length; i++) {
+      for (let i = 0; i < _.keys(abstract).length; i += 1) {
         const name = _.keys(abstract).sort()[i];
         multi.push(['property.ejs', {
           name,
@@ -231,7 +233,9 @@ const generateMarkdown = (filename, schema, schemaPath, outDir, dependencyMap, d
   }
   const propertiesSlugs = createGithubSlugs(_.keys(schema.properties));
   if (_.keys(schema.properties).length > 0) {
-    if (schema.required === undefined) { schema.required = []; }
+    if (schema.required === undefined) {
+      schema.required = [];
+    }
     schema.required = _.union(schema.required, required);
     // table of contents
     multi.push(['properties.ejs', {
@@ -243,7 +247,7 @@ const generateMarkdown = (filename, schema, schemaPath, outDir, dependencyMap, d
       i18n,
     }]);
     // regular properties
-    for (let i = 0; i < _.keys(schema.properties).length; i++) {
+    for (let i = 0; i < _.keys(schema.properties).length; i += 1) {
       const name = _.keys(schema.properties).sort()[i];
       multi.push(['property.ejs', {
         name,
@@ -259,7 +263,7 @@ const generateMarkdown = (filename, schema, schemaPath, outDir, dependencyMap, d
 
   if (_.keys(schema.patternProperties).length > 0) {
     // patterns properties
-    for (let i = 0; i < _.keys(schema.patternProperties).length; i++) {
+    for (let i = 0; i < _.keys(schema.patternProperties).length; i += 1) {
       const name = _.keys(schema.patternProperties)[i];
       multi.push(['pattern-property.ejs', {
         name,
@@ -293,10 +297,12 @@ const generateMarkdown = (filename, schema, schemaPath, outDir, dependencyMap, d
 
   return Promise.reduce(Promise.map(multi, render), build, '').then((str) => {
     const mdfile = `${path.basename(filename).slice(0, -5)}.md`;
-    return writeFile(path.join(path.join(outDir), path.dirname(filename.substr(schemaPath.length))), mdfile, prettyMarkdown(str));
-  }).then(out =>
-    // console.log('markdown written (promise)', out);
-    out);
+    return writeFile(
+      path.join(outDir, path.dirname(filename.substr(schemaPath.length))),
+      mdfile,
+      prettyMarkdown(str),
+    );
+  });
 };
 
 module.exports = generateMarkdown;
diff --git a/lib/prettyMarkdown.js b/lib/prettyMarkdown.js
index f47b710fb60ef4628bc1bfc75564ebfe28a4bdd3..89a4df5b3ac8160821805f8c09439c0b4fcf4217 100644
--- a/lib/prettyMarkdown.js
+++ b/lib/prettyMarkdown.js
@@ -12,8 +12,6 @@
 
 const prettier = require('prettier');
 
-const prettyMarkdown = function (str) {
-  return prettier.format(str, { parser: 'markdown', proseWrap: 'always', printWidth: 119 });
-};
+const prettyMarkdown = str => prettier.format(str, { parser: 'markdown', proseWrap: 'always', printWidth: 119 });
 
 module.exports = prettyMarkdown;
diff --git a/lib/readSchemaFile.js b/lib/readSchemaFile.js
index 3a8002ef393d4d69c7843496bfb35a1a07247546..294ffc7d277478a341d2379784cb2f055327927e 100644
--- a/lib/readSchemaFile.js
+++ b/lib/readSchemaFile.js
@@ -10,6 +10,8 @@
  * governing permissions and limitations under the License.
  */
 
+/* eslint-disable no-param-reassign */
+
 const Promise = require('bluebird');
 const fs = Promise.promisifyAll(require('fs'));
 
@@ -22,26 +24,24 @@ const fs = Promise.promisifyAll(require('fs'));
  * @param {map} schemaPathMap - the map of schema paths and JSON schemas
  * @param {*} fullPath - the full path to the schema
  */
-module.exports = function readSchemaFile(schemaPathMap, fullPath) {
-  if (!schemaPathMap) {
-    schemaPathMap = {};
-  }
-  return fs.readFileAsync(fullPath)
-    .then((data) => {
-      const schema = JSON.parse(data);
-      const obj = {};
-      obj.filePath = fullPath;
-      obj.jsonSchema = schema;
-      if (schema.$id && schema.$id.length > 0) {
-        if (!schemaPathMap[schema.$id]) {
-          schemaPathMap[schema.$id] = obj;
-        }
-      // TODO err
-      // TODO check Missing Specific properties to throw warning // function for warning
-      } else {
-        console.warn(`schema ${fullPath} has no $id`);
-        schemaPathMap[fullPath] = obj;
+const readSchemaFile = (schemaPathMap, fullPath) => {
+  schemaPathMap = schemaPathMap || {};
+  return fs.readFileAsync(fullPath).then((data) => {
+    const schema = JSON.parse(data);
+    const obj = {};
+    obj.filePath = fullPath;
+    obj.jsonSchema = schema;
+    if (schema.$id && schema.$id.length > 0) {
+      if (!schemaPathMap[schema.$id]) {
+        schemaPathMap[schema.$id] = obj;
       }
-      return schemaPathMap;
-    });
+    } else {
+      // eslint-disable-next-line no-console
+      console.warn(`schema ${fullPath} has no $id`);
+      schemaPathMap[fullPath] = obj;
+    }
+    return schemaPathMap;
+  });
 };
+
+module.exports = readSchemaFile;
diff --git a/lib/readmeWriter.js b/lib/readmeWriter.js
index 98062032ae784802d4e28b1e88bfbdc7ba4e6cb3..eb3be7f3d698e16adcba35fd5bd825e221a28003 100644
--- a/lib/readmeWriter.js
+++ b/lib/readmeWriter.js
@@ -10,6 +10,8 @@
  * governing permissions and limitations under the License.
  */
 
+/* eslint-disable no-param-reassign */
+
 const Promise = require('bluebird');
 const _ = require('lodash');
 const ejs = require('ejs');
@@ -21,7 +23,7 @@ const i18n = require('i18n');
 const prettyMarkdown = require('./prettyMarkdown');
 const writeFile = require('./writeFiles');
 
-function relativePath(full, base) {
+const relativePath = (full, base) => {
   full = full.replace(/\\/g, '/');
   base = base.replace(/\\/g, '/');
   if (full.indexOf(base) === 0) {
@@ -29,11 +31,9 @@ function relativePath(full, base) {
   } else {
     return full;
   }
-}
+};
 
-function directory(full, base) {
-  return relativePath(full, base).replace(/[^\/]+$/, '');
-}
+const directory = (full, base) => relativePath(full, base).replace(/[^/]+$/, '');
 
 /**
  * Generates a README.md file from the `schemas` passed in at directory `out`
@@ -42,7 +42,7 @@ function directory(full, base) {
  * @param {string} out - output directory
  * @param {string} base - schema base directory
  */
-const generateReadme = function (paths, schemas, out, base) {
+const generateReadme = (paths, schemas, out, base) => {
   const coreinfo = _.values(schemas).map(schema => ({
     id: schema.jsonSchema.$id,
     title: schema.jsonSchema.title,
@@ -61,12 +61,7 @@ const generateReadme = function (paths, schemas, out, base) {
     core: coreinfo,
     groups: _.groupBy(coreinfo, key => key.dir),
   };
-  return pejs.renderFileAsync(path.join(__dirname, '../templates/md/readme.ejs'), ctx, { debug: false }, i18n).then((str) => {
-    console.log('Writing README');
-    return writeFile(out, 'README.md', prettyMarkdown(str));
-  }).then(out =>
-    // console.log('markdown written (promise)', out);
-    out);
+  return pejs.renderFileAsync(path.join(__dirname, '../templates/md/readme.ejs'), ctx, { debug: false }, i18n).then(str => writeFile(out, 'README.md', prettyMarkdown(str)));
 };
 
 module.exports = generateReadme;
diff --git a/lib/schema.js b/lib/schema.js
index e8c7ec42d51425b2e19766814dd7e31415b86ef8..88113ef3a3ee9d98ae283613391c3793f2beeb9a 100644
--- a/lib/schema.js
+++ b/lib/schema.js
@@ -10,40 +10,42 @@
  * governing permissions and limitations under the License.
  */
 
+/* eslint-disable no-param-reassign, no-console, no-use-before-define */
+
 const path = require('path');
 const _ = require('lodash');
 const logger = require('winston');
 const readdirp = require('readdirp');
 const Promise = require('bluebird');
 const fs = Promise.promisifyAll(require('fs'));
+const pointer = require('json-pointer');
 const markdownWriter = require('./markdownWriter');
 const schemaWriter = require('./schemaWriter');
 const readmeWriter = require('./readmeWriter');
 
 const deff = '#/definitions/';
 const absUrlRegex = new RegExp('^(?:[a-z]+:)?//', 'i');
-const pointer = require('json-pointer');
 
 let smap; // TODO remove global
 let sPath;
 const wmap = {};
 function get$refType(refValue) {
-  let startpart = ''; let endpart = ''; var
-    refType = '';
+  let startpart = '';
+  let endpart = '';
+  let refType = '';
   const arr = refValue.split('#');
-  if (arr.length > 1) { endpart = arr[1]; }
+  if (arr.length > 1) {
+    // eslint-disable-next-line prefer-destructuring
+    endpart = arr[1];
+  }
 
+  // eslint-disable-next-line prefer-destructuring
   startpart = arr[0];
-  // TODO yRelNoDef
-  // relative-- yRelWithDef, yRelNoDef,
-  // absolute-- yAbsWithDef, yAbsFSchema, yAbsWithFragment
-  var refType = '';
-  const deff = '/definitions/';
 
   // if( absUrlRegex.test(refVal) ){
   if (startpart.length > 1) {
     if (startpart in smap) {
-      if (endpart.startsWith(deff)) {
+      if (endpart.startsWith('/definitions/')) {
         refType = 'yAbsWithDef';
       } else if (endpart.length === 0) {
         refType = 'yAbsFSchema';
@@ -51,7 +53,7 @@ function get$refType(refValue) {
         refType = 'yAbsWithFragment';
       }
     }
-  } else if (endpart.startsWith(deff)) {
+  } else if (endpart.startsWith('/definitions/')) {
     refType = 'yRelWithDef';
   }
   //  }
@@ -60,20 +62,24 @@ function get$refType(refValue) {
 
 function normaliseLinks(obj, refArr) {
   const basepath = refArr.startpart;
-  let $linkVal = ''; let
-    $linkPath = '';
+  let $linkVal = '';
+  let $linkPath = '';
   if (basepath in smap) {
     const newpath = path.relative(path.dirname(sPath), smap[basepath].filePath).replace(/\\/g, '/'); // to cater windows paths
     const temp = newpath.slice(0, -5).split('/');
     $linkVal = obj.title ? obj.title : path.basename(newpath).slice(0, -5);
     $linkPath = `${temp.join('/')}.md`;
     return { $linkVal, $linkPath };
+  } else {
+    return undefined;
   }
 }
 const resolve$ref = Promise.method((val, base$id) => {
-  let obj; let
-    link;
-  if (!(base$id in wmap)) { wmap[base$id] = {}; }
+  let obj;
+  let link;
+  if (!(base$id in wmap)) {
+    wmap[base$id] = {};
+  }
   const refArr = get$refType(val.$ref);
   if (refArr.refType === 'yRelWithDef') {
     refArr.startpart = base$id;
@@ -103,8 +109,9 @@ const resolve$ref = Promise.method((val, base$id) => {
       return processISchema(ischema, refArr.startpart);
     }
   }
+  return undefined;
 });
-var processFurther = Promise.method((val, key, $id) => {
+const processFurther = Promise.method((val, key, $id) => {
   const base$id = $id;
   if (val.$ref) {
     return resolve$ref(val, base$id);
@@ -135,6 +142,7 @@ var processFurther = Promise.method((val, key, $id) => {
           // go recursively down to check for a $ref
           return processFurther(propertyValue, propertyKey, base$id);
         }
+        return undefined;
       });
 
       return val;
@@ -143,9 +151,10 @@ var processFurther = Promise.method((val, key, $id) => {
     return val;
   }
 });
-function processISchema() {} // define w/ function so it gets hoisted and we avoid eslint errors about what is defined first: processISchema or resolve$ref. Both rely on each other!
-processISchema = Promise.method((schema, base$id) => {
-  if (!(base$id in wmap)) { wmap[base$id] = {}; }
+const processISchema = Promise.method((schema, base$id) => {
+  if (!(base$id in wmap)) {
+    wmap[base$id] = {};
+  }
   if (schema.anyOf || schema.oneOf) {
     // var $definitions=[]
     schema.type = schema.anyOf ? 'anyOf' : 'oneOf';
@@ -169,16 +178,13 @@ processISchema = Promise.method((schema, base$id) => {
 
   if (schema.items) {
     const val = schema.items;
-    if (!schema.type) { schema.type = 'array'; }
-    if (_.isArray(val)) {
-      // TODO
-
-    } else if (val.$ref) {
+    if (!schema.type) {
+      schema.type = 'array';
+    }
+    if (val.$ref && !_.isArray(val)) {
       resolve$ref(val, base$id).then((piSchema) => { // check // not sending correct id
         schema.items = piSchema;
       });
-    } else {
-      // TODO if such a scenario
     }
   }
   // schema.$definitions = $definitions
@@ -186,15 +192,19 @@ processISchema = Promise.method((schema, base$id) => {
 });
 function processSchema(schema) {
   return new Promise((resolve, reject) => {
-    if (!schema.properties) { schema.properties = {}; }
+    if (!schema.properties) {
+      schema.properties = {};
+    }
     const $id = schema.$id || schema.id;
     const base$id = $id;
-    if (!(base$id in wmap)) { wmap[base$id] = {}; }
+    if (!(base$id in wmap)) {
+      wmap[base$id] = {};
+    }
     if (schema.allOf) {
       _.each(schema.allOf, (value) => {
         if (value.$ref) {
-          let obj; let
-            link;
+          let obj;
+          let link;
           const refArr = get$refType(value.$ref);
           if (refArr.refType === 'yRelWithDef') {
             refArr.startpart = base$id;
@@ -242,10 +252,12 @@ function processSchema(schema) {
                         schema.properties[key].$oSchema.$linkPath = link.$linkPath;
                       }
                       if (ischema.required) {
-                        if (key in ischema.required) { schema.required.push(key); }
+                        if (key in ischema.required) {
+                          schema.required.push(key);
+                        }
                       }
                     } else {
-                      reject('No further schema found');
+                      reject(new Error('No further schema found'));
                     }
                   });
                 });
@@ -287,12 +299,12 @@ function processSchema(schema) {
 }
 
 
-const Schema = function (ajv, schemaMap) {
+const Schema = (ajv, schemaMap) => {
   this._ajv = ajv;
   this._schemaPathMap = schemaMap;
 };
 
-Schema.resolveRef = function (key, obj, currpath) {
+Schema.resolveRef = (key, obj, currpath) => {
   if (key === '$ref') {
     const refVal = obj[key];
     let temp;
@@ -320,27 +332,14 @@ Schema.resolveRef = function (key, obj, currpath) {
       obj.$linkPath = `${temp.join('/')}.md`;
     }
   }
-  if (key === 'anyOf' || key === 'oneOf' || key === 'allOf') { obj.$type = key; }
-};
-
-/* The following function does not seem to be used anymore!
-var traverseSchema = function(object,schemaFilePath){
-  return new Promise((resolve,reject) => {
-    var recurse=function(curr,key,prev){
-      if (key){
-        if (key === 'anyOf' || key === 'oneOf' || key === 'allOf') {prev.$type=key;}
-      }
-      var result;
-      if (Array.isArray(curr)) {curr.map((item,index) => recurse(item,index,curr));} else {
-        (typeof curr === 'object') ? Object.keys(curr).map(key => recurse(curr[key],key,curr)):Schema.resolveRef(key,prev,schemaFilePath);
-      }
-      return object;
-    };
-    resolve(recurse(object));
-  });
+  if (key === 'anyOf' || key === 'oneOf' || key === 'allOf') {
+    obj.$type = key;
+  }
 };
-*/
 
+// TODO: For some exceedingly strange reason this generates test failures
+// when an arrow function is used…
+// eslint-disable-next-line func-names
 Schema.getExamples = function (filePath, schema) {
   const exampleFileNames = [];
   let examples = [];
@@ -352,13 +351,17 @@ Schema.getExamples = function (filePath, schema) {
       .on('data', entry => exampleFileNames.push(entry.fullPath))
       .on('end', () => resolve(exampleFileNames))
       .on('error', err => reject(err));
-  }).then((exampleFileNames) => {
+  }).then(() => {
     if (exampleFileNames.length > 0) {
       const validate = this._ajv.compile(schema);
       return Promise.map(exampleFileNames, entry => fs.readFileAsync(entry).then((example) => {
         const data = JSON.parse(example.toString());
         const valid = validate(data);
-        if (valid) { examples.push({ filename: entry, data }); } else { logger.error(`${entry} is an invalid Example`); }
+        if (valid) {
+          examples.push({ filename: entry, data });
+        } else {
+          logger.error(`${entry} is an invalid Example`);
+        }
       })).then(() => {
         // Sort according to filenames in order not to have random prints
         examples.sort((a, b) => (a.filename > b.filename ? 1 : -1));
@@ -367,11 +370,13 @@ Schema.getExamples = function (filePath, schema) {
         schema.examples = examples;
         return schema;
       });
-    } else { return schema; }
+    } else {
+      return schema;
+    }
   });
 };
 
-Schema.getDescription = function (filePath, schema) {
+Schema.getDescription = (filePath, schema) => {
   let temp = path.basename(filePath, path.extname(filePath));
   // TODO should err be thrown here?
   temp = `${temp.split('.')[0]}.description.md`;
@@ -383,10 +388,16 @@ Schema.getDescription = function (filePath, schema) {
     .catch(() => schema);
 };
 
+// TODO: For some exceedingly strange reason this generates test failures
+// when an arrow function is used…
+// eslint-disable-next-line func-names
 Schema.setAjv = function (ajv) {
   this._ajv = ajv;
 };
 
+// TODO: For some exceedingly strange reason this generates test failures
+// when an arrow function is used…
+// eslint-disable-next-line func-names
 Schema.setSchemaPathMap = function (schemaMap) {
   this._schemaPathMap = schemaMap;
 };
@@ -395,17 +406,20 @@ Schema.setSchemaPathMap = function (schemaMap) {
  * @param {*} schemaMap
  * @param {*} schemaPath
  * @param {string} docDir - where documentation will be generated
- * @param {string} schemaDir - where schemas will be generated, if not set, no schema's will be output
- * @param {map} metaElements - a map of additional YAML frontmatter to be added to the generated Markdown
+ * @param {string} schemaDir - where schemas will be generated, if not set, no schema's
+ *   will be output
+ * @param {map} metaElements - a map of additional YAML frontmatter to be added to
+ *   the generated Markdown
  * @param {boolean} readme - generate a README.md directory listing
  * @param {map} docs - a map of documentation links for headers
  */
-Schema.process = function (schemaMap, schemaPath, docDir, schemaDir, metaElements, readme, docs, consoleArgs) {
+Schema.process = (schemaMap, schemaPath, docDir, schemaDir,
+  metaElements, readme, docs, consoleArgs) => {
   smap = schemaMap;
   const keys = Object.keys(schemaMap);
   return Promise.mapSeries(keys, (schemaKey) => {
     const props = Object.keys(wmap);
-    for (let i = 0; i < props.length; i++) {
+    for (let i = 0; i < props.length; i += 1) {
       delete wmap[props[i]];
     }
 
@@ -425,9 +439,26 @@ Schema.process = function (schemaMap, schemaPath, docDir, schemaDir, metaElement
           return { mSchema, wSchema: allSchema, dep: wmap };
         });
       }).then((object) => {
-        const outputTasks = [markdownWriter(schemaMap[schemaKey].filePath, object.mSchema, schemaPath, docDir, object.dep, docs, consoleArgs)];
+        const outputTasks = [
+          markdownWriter(
+            schemaMap[schemaKey].filePath,
+            object.mSchema,
+            schemaPath,
+            docDir,
+            object.dep,
+            docs,
+            consoleArgs,
+          ),
+        ];
         if (schemaDir !== '') {
-          outputTasks.push(schemaWriter(schemaMap[schemaKey].filePath, object.wSchema, schemaPath, schemaDir));
+          outputTasks.push(
+            schemaWriter(
+              schemaMap[schemaKey].filePath,
+              object.wSchema,
+              schemaPath,
+              schemaDir,
+            ),
+          );
         }
         return Promise.all(outputTasks);
       })
@@ -442,7 +473,7 @@ Schema.process = function (schemaMap, schemaPath, docDir, schemaDir, metaElement
       const markdowns = result.map(r => r[0]);
       return readmeWriter(markdowns, schemaMap, docDir, schemaPath);
     } else {
-      console.log('Output processed.');
+      return undefined;
     }
   });
 };
diff --git a/lib/schemaWriter.js b/lib/schemaWriter.js
index c06d24055ec3d48ddccd4155ff891d772b960a9e..5b8e7d6ed0e029949a644783fe0106a37f8a0b81 100644
--- a/lib/schemaWriter.js
+++ b/lib/schemaWriter.js
@@ -13,8 +13,10 @@
 const path = require('path');
 const writeFile = require('./writeFiles');
 
-const generateNewSchemaFiles = function (filename, schema, schemaPath, outDir) {
-  return writeFile(path.join(path.join(outDir), path.dirname(filename.substr(schemaPath.length))), path.basename(filename), JSON.stringify(schema, null, 4));
-};
+const generateNewSchemaFiles = (filename, schema, schemaPath, outDir) => writeFile(
+  path.join(outDir, path.dirname(filename.substr(schemaPath.length))),
+  path.basename(filename),
+  JSON.stringify(schema, null, 4),
+);
 
 module.exports = generateNewSchemaFiles;
diff --git a/lib/writeFiles.js b/lib/writeFiles.js
index b4cf524bce7da347622833070065d960e0bb7965..848080dd65d5163242543b69491be516f16ea314 100644
--- a/lib/writeFiles.js
+++ b/lib/writeFiles.js
@@ -15,12 +15,13 @@ const fs = Promise.promisifyAll(require('fs'));
 const path = require('path');
 const mkdirp = Promise.promisify(require('mkdirp'));
 
-const writeFile = function (outputDir, fileName, data) {
+const writeFile = (outputDir, fileName, data) => Promise.resolve().then(() => {
   if (!fs.existsSync(outputDir)) {
-    return mkdirp(outputDir).then(() => fs.writeFileAsync(path.join(outputDir, fileName), data).then(() => path.join(outputDir, fileName)));
+    return mkdirp(outputDir);
   } else {
-    return fs.writeFileAsync(path.join(outputDir, fileName), data).then(() => path.join(outputDir, fileName));
+    return Promise.resolve();
   }
-};
+}).then(() => fs.writeFileAsync(path.join(outputDir, fileName), data))
+  .then(() => path.join(outputDir, fileName));
 
 module.exports = writeFile;
diff --git a/spec/lib/header.spec.js b/spec/lib/header.spec.js
index a7f38ce991391dd44a20a688f53f97234fb7793c..6663fbfd40a55a41da93a70d83f2f007ded77c5a 100644
--- a/spec/lib/header.spec.js
+++ b/spec/lib/header.spec.js
@@ -14,10 +14,11 @@
 
 const i18n = require('i18n');
 const path = require('path');
+const diff = require('jasmine-diff');
 const { Header, headers } = require('../../lib/header');
 
 beforeEach(() => {
-  jasmine.addMatchers(require('jasmine-diff')(jasmine, {
+  jasmine.addMatchers(diff(jasmine, {
     colors: true,
     inline: true,
   }));
diff --git a/spec/lib/integrationTest.spec.js b/spec/lib/integrationTest.spec.js
index 9b07850f4c912bf3208ca262f8a9c9550bc86a23..9be1e277f7bf06d93afbbba6a23f27b1ed529330 100644
--- a/spec/lib/integrationTest.spec.js
+++ b/spec/lib/integrationTest.spec.js
@@ -15,11 +15,12 @@
 const { spawn } = require('child_process');
 const path = require('path');
 const { readFileSync, readdirSync, statSync } = require('fs');
+const diff = require('jasmine-diff');
 
 beforeEach(() => {
   jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
   jasmine.addMatchers(
-    require('jasmine-diff')(jasmine, {
+    diff(jasmine, {
       colors: true,
       inline: true,
     }),
@@ -68,22 +69,22 @@ describe('Compare results', () => {
     ]);
     ls.on('close', (code) => {
       expect(code).toEqual(0);
-      const files = readdirSync('./spec/examples').filter(item => !(/(^|\/)\.[^\/\.]/g).test(item));
+      const files = readdirSync('./spec/examples').filter(item => !(/(^|\/)\.[^/.]/g).test(item));
       expect(files.length).toEqual(23);
 
       files.forEach((file) => {
         if (statSync(`./spec/examples/${file}`).isFile()) {
           const expectedstr = readFileSync(path.resolve('./spec/examples/', file)).toString();
           let actualstr = readFileSync(path.resolve('./examples/docs/', file)).toString();
-          actualstr=actualstr.replace(/\r\n/g, '\n');
-          expect(actualstr).toEqual(expectedstr, file + ' does not match');
+          actualstr = actualstr.replace(/\r\n/g, '\n');
+          expect(actualstr).toEqual(expectedstr, `${file} does not match`);
         }
       });
 
       done();
     });
   });
-  it('Run jsonschema2md for a file and do not generate a header', done => {
+  it('Run jsonschema2md for a file and do not generate a header', (done) => {
     const ls = spawn('node', [
       'cli.js',
       '-d',
@@ -94,17 +95,17 @@ describe('Compare results', () => {
       'examples/generated-schemas',
       '--no-header',
       '-v',
-      '06'
+      '06',
     ]);
 
-    ls.on('close', code => {
+    ls.on('close', (code) => {
       expect(code).toEqual(0);
-      const files = readdirSync('./spec/examples/withoutHeader').filter(item => !(/(^|\/)\.[^\/\.]/g).test(item));
-      files.forEach(file => {
-        if (statSync('./spec/examples/withoutHeader/' + file).isFile()) {
+      const files = readdirSync('./spec/examples/withoutHeader').filter(item => !(/(^|\/)\.[^/.]/g).test(item));
+      files.forEach((file) => {
+        if (statSync(`./spec/examples/withoutHeader/${file}`).isFile()) {
           const expectedstr = readFileSync(path.resolve('./spec/examples/withoutHeader/', file)).toString();
-          let actualstr = readFileSync(path.resolve('./examples/docsWithoutHeader/', file)).toString();
-          expect(actualstr).toEqual(expectedstr, file + ' does not match');
+          const actualstr = readFileSync(path.resolve('./examples/docsWithoutHeader/', file)).toString();
+          expect(actualstr).toEqual(expectedstr, `${file} does not match`);
         }
       });
       done();