diff --git a/cli.js b/cli.js
new file mode 100644
index 0000000000000000000000000000000000000000..5ca576ddfb8e0ffad5fb4cabaf3093554d98859d
--- /dev/null
+++ b/cli.js
@@ -0,0 +1,120 @@
+#! /usr/bin/env node
+/**
+ * Copyright 2017 Adobe Systems Incorporated. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+var logger = require('winston');
+var Promise = require('bluebird');
+var path = require('path');
+var _ = require('lodash');
+var fs = Promise.promisifyAll(require('fs'));
+var readdirp = require('readdirp');
+var Ajv = require('ajv');
+
+var processFile = require('./lib/main');
+var Schema = require('./lib/schema');
+var readSchemaFile = require('./lib/readSchemaFile');
+
+// parse/process command line arguments
+var argv = require('optimist')
+.usage('Generate Markdown documentation from JSON Schema.\n\nUsage: $0')
+.demand('d')
+.alias('d', 'input')
+// TODO: is baseURL still a valid parameter?
+.describe('d', 'path to directory containing all JSON Schemas or a single JSON Schema file. This will be considered as the baseURL. Note that only files ending in .schema.json will be processed.')
+.alias('o', 'out')
+.describe('o', 'path to output directory')
+.default('o', path.resolve(path.join('.', 'out')))
+.alias('m', 'meta')
+.describe('m','add metadata elements to .md files Eg -m template=reference. Multiple values can be added by repeating the flag Eg: -m template=reference -m hide-nav=true')
+.alias('s','metaSchema')
+.describe('s', 'Custom meta schema path to validate schemas')
+.alias('x', 'schema-out')
+.describe('x', 'output JSON Schema files including description and validated examples in the _new folder at output directory')
+.check(function (args) {
+  if (!fs.existsSync(args.input)) {
+    throw 'Input file "' + args.input + '" does not exist!';
+  }
+  if (args.s && !fs.existsSync(args.s)) {
+    throw 'Meta schema file "' + args.s + '" does not exist!';
+  }
+})
+.argv;
+
+var ajv = new Ajv({ allErrors: true , messages:true });
+ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));
+var schemaPathMap = {};
+var metaElements = {};
+var schemaPath = path.resolve(argv.d);
+var outDir = path.resolve(argv.o);
+var target = fs.statSync(schemaPath);
+
+if(argv.s){
+  ajv.addMetaSchema(require(path.resolve(argv.s)));
+}
+
+if (argv.m) {
+  if(_.isArray(argv.m)){
+    _.each(argv.m,function(item){
+      var meta=item.split('=');
+      if (meta.length === 2) {
+        metaElements[meta[0]] = meta[1];
+      }
+    });
+  } else {
+    var meta=(argv.m).split('=');
+    if (meta.length === 2) {
+      metaElements[meta[0]] = meta[1];
+    }
+  }
+}
+
+logger.info('output directory: %s', outDir);
+if (target.isDirectory()) {
+  // the ajv json validator will be passed into the main module to help with processing
+  var files=[];
+  readdirp({ root: schemaPath, fileFilter: '*.schema.json' })
+  .on('data',(entry) => {
+    files.push(entry.fullPath);
+    ajv.addSchema(require(entry.fullPath), entry.fullPath);
+  })
+  .on('end',() => {
+    Schema.setAjv(ajv);
+    Schema.setSchemaPathMap(schemaPathMap);
+    return Promise.reduce(files, readSchemaFile, schemaPathMap)
+    .then((schemaMap)=>{
+      logger.info('finished reading all *.schema.json files in %s, beginning processing....', schemaPath);
+      return Schema.load(schemaMap, schemaPath, outDir, metaElements);
+    })
+    .then(() => {
+      logger.info('Processing complete.');
+    })
+    .catch((err) => {
+      logger.error(err);
+      process.exit(1);
+    });
+  })
+  .on('error',(err)=>{
+    logger.error(err);
+    process.exit(1);
+  });
+} else {
+  readSchemaFile(schemaPathMap, schemaPath)
+  .then((schemaMap) => {
+    ajv.addSchema(require(schemaPath), schemaPath);
+    Schema.setAjv(ajv);
+    Schema.setSchemaPathMap(schemaPathMap);
+    logger.info('finished reading %s, beginning processing....', schemaPath);
+    return Schema.load(schemaMap , schemaPath, outDir, metaElements);
+  })
+  .then(() => {
+    logger.info('Processing complete.');
+  })
+  .catch((err) => {
+    logger.error(err);
+    process.exit(1);
+  });
+}
diff --git a/lib/main.js b/lib/main.js
old mode 100755
new mode 100644
index 73cc043b99972454353e3600002d375605d624a3..9ce1b84660146314a874c846ab63cdc250c955df
--- a/lib/main.js
+++ b/lib/main.js
@@ -5,138 +5,8 @@
  * of the License at http://www.apache.org/licenses/LICENSE-2.0
  */
 
-'use strict';
-var Promise=require('bluebird');
-var fs = Promise.promisifyAll(require('fs'));
-var path = require('path');
-var _ = require('lodash');
-var async = require('async');
-var logger = require('winston');
-var readdirp = require('readdirp');
-var Schema = require('./schema');
-var Ajv = require('ajv');
-var ajv = new Ajv({ allErrors: true , messages:true});
-ajv.addMetaSchema(require('ajv/lib/refs/json-schema-draft-04.json'));
-
-
-// parse/process command line arguments
-
-var argv = require('optimist')
-.usage('Generate Markdown documentation from JSON Schema.\n\nUsage: $0')
-.demand('d')
-.alias('d', 'input')
-.describe('d', 'path to directory containing all JSON Schemas or a single JSON Schema file. This will be considered as the baseURL')
-.alias('f','isFile')
-.describe('f','pass if input is a file path')
-.alias('o', 'out')
-.describe('o', 'path to output directory (default: ./out)')
-.alias('m', 'meta')
-.describe('m','add metadata elements to .md files Eg -m template=reference. Multiple values can be added by repeating the flag Eg: -m template=reference -m hide-nav=true')
-.alias('s','metaSchema')
-.describe('s', 'Custom meta schema path to validate schemas')
-.alias('x', 'schema-out')
-.describe('x', 'pass to output JSON Schema files including description and validated examples in the _new folder at output directory')
-.argv;
-
-if (!argv.d) {
-  process.exit(1);
-}
-var schemaPathMap={};
-var schemaPath = path.resolve(argv.d);
-var fileDir=schemaPath;
-var baseName = path.basename(schemaPath).replace(/\.[^/.]+$/, '');
-var outDir = path.resolve(argv.o || './out');
-var metaElements={};
-if(argv.f){
-  fileDir=path.dirname(schemaPath);
-}
-if (argv.m) {
-  if(_.isArray(argv.m)){
-    _.each(argv.m,function(item){
-      var meta=item.split("=");
-      if(meta.length == 2)
-        metaElements[meta[0]]=meta[1];
-    });
-  }
-  else {
-    var meta=(argv.m).split("=");
-    if(meta.length == 2)
-    metaElements[meta[0]]=meta[1];
-  }
-
-}
-if(argv.s){
-  ajv.addMetaSchema(require(path.resolve(argv.s)));
-}
-
-var baseURL = path.resolve(fileDir);
-logger.info('output directory: %s', outDir);
-logger.info('processing %s...', schemaPath);
-
-var readSchemaFiles=function(fullpath){
-  return fs.readFileAsync(fullpath).then((data)=>{
-    let schema = JSON.parse(data);
-    let 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 {
-      schemaPathMap[fullpath] = obj;
-    }
-  })
-}
-
-//Function to generate Markdown for all files in a folder
-var GenerateForAllFiles = function (dirname) {
-  var files=[];
-  return new Promise((resolve,reject) => {
-    readdirp({ root: dirname, fileFilter: '*.schema.json' })
-    .on('data',(entry) => {
-      files.push(  entry.fullPath  );
-      ajv.addSchema(require(entry.fullPath),entry.fullPath);
-    })
-    .on('end',()=>resolve(files))
-    .on('error',(err)=>{
-      reject(err);
-    })
-  }).then((schemaFiles) => {
-    Schema.setAjv(ajv);
-    Schema.setSchemaPathMap(schemaPathMap);
-    return Promise.map(schemaFiles,readSchemaFiles)
-    .then(() => {
-      logger.info("Read Schema files!!!")
-      return Schema.load(schemaPathMap,schemaPath,outDir,metaElements)
-
-    })
-
-  })
-}
-
-
-if(argv.f){
-  //generating markdown for a single file
-  readSchemaFiles(schemaPath).then(()=>{
-    ajv.addSchema(require(schemaPath),schemaPath);
-    Schema.setAjv(ajv);
-    Schema.setSchemaPathMap(schemaPathMap);
-    logger.info("Read Schema files!!!");
-    Schema.load( schemaPathMap , schemaPath, outDir, metaElements)
-    .then(()=>{logger.info("Done!!!")})
-    .catch((err) => {
-      logger.error("Error Occurred. Processing Incomplete!!!")
-      logger.error(err)})
-    })
-  }
-  else {
-    GenerateForAllFiles(schemaPath)
-    .then(()=>{logger.info("Done!!!")})
-    .catch((err) => {
-      logger.error("Error Occurred. Processing Incomplete!!!")
-      logger.error(err)
-    })
-  }
+module.exports = {
+  writer:require('./writeFiles'),
+  reader:require('./readSchemaFile'),
+  schema:require('./schema')
+};
diff --git a/lib/readSchemaFile.js b/lib/readSchemaFile.js
new file mode 100644
index 0000000000000000000000000000000000000000..5ef273b8b60ce637e5ce1061502398d1019c9f3f
--- /dev/null
+++ b/lib/readSchemaFile.js
@@ -0,0 +1,34 @@
+/**
+ * Copyright 2017 Adobe Systems Incorporated. All rights reserved.
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License. You may obtain a copy
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
+ */
+
+var Promise=require('bluebird');
+var fs = Promise.promisifyAll(require('fs'));
+
+// Reads a schema file and modifies a schema path map object based on the schema file.
+// Returns the schema path map object.
+module.exports = function readSchemaFile(schemaPathMap, fullPath) {
+  if (!schemaPathMap) {
+      schemaPathMap = {};
+  }
+  return fs.readFileAsync(fullPath)
+  .then((data)=>{
+    let schema = JSON.parse(data);
+    let 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 {
+      schemaPathMap[fullPath] = obj;
+    }
+    return schemaPathMap;
+  });
+};
diff --git a/package.json b/package.json
index d41464391a7a2cb59d9cc2d3dce500ff14411f6a..e084bd0bf816f55cc0004aca6217844f658bdd96 100644
--- a/package.json
+++ b/package.json
@@ -4,10 +4,10 @@
   "version": "0.2.0",
   "main": "lib/main.js",
   "bin": {
-    "jsonschema2md": "./index.js"
+    "jsonschema2md": "./cli.js"
   },
   "scripts": {
-    "start": "node ./index.js",
+    "start": "node cli.js",
     "test": "jasmine"
   },
   "dependencies": {