whole_func_string: function fileLineReader(filepath, opts){
      if(typeof arguments[0] !== 'string'){
          opts = arguments[0];
          filepath = opts.file || opts.filename || opts.filepath;
      }
  
      filepath = resolve(filepath).fullPath;
  
      opts = opts || {};
      var chunkSize = opts.chunkSize || 1;
      var hasHeader = opts.header || opts.headers || opts.hasHeader;
      var headLine;
      var instream = fs.createReadStream(filepath, opts);
      var outstream = new Stream();
      var rl = readline.createInterface(instream, outstream);
      var onData;
      
      var done;
      instream.on('error', function(err) {
          rl.closed = true;
          rl.close();
          if(done) done(err);
          else throw err;
      });
      
      opts.separator = opts.separator || opts.delimiter;
  
      var lineParser = opts.lineParser || function(line){
          if(!opts.separator) return line;
          return line.split(opts.separator);
      };
  
      var lines = [];
      var lineError;
      var index = -1;
      var limit = 1;
      
      function getLines(numOfLines, cb){
          if(arguments.length === 0) cb = arguments[0];
          if(typeof cb !== 'function') throw new Error('Wrong arguments');
          
          done = cb;
          
          index = index === -1 ? -1 : 0;
          limit = numOfLines || 1;
          var result;
          
          if(lines.length===0) index = -1; // fix - when paused on chunkSize
          if(lines.length >= limit) {
              result = lines.slice(0, limit);
              lines.splice(0,limit);
              return cb(null, result);
          }
          
          if(rl.closed){
              result = lines.slice();
              lines = [];
              return cb(null, result);
          }
          
          onData = cb;
          rl.resume();
      }
  
      rl.on('line', function(line) {
          index++;
  
          line = lineParser(line);
          
          if(headLine){
              var lineWithHeader = {};
              for(var i=0;i<headLine.length;i++){
                  lineWithHeader[ headLine[i] ] = line[i];
              }
              line = lineWithHeader;
          }
          else if(index===0 && hasHeader){
              headLine = line;
              index--;
              return;
          }
  
          lines.push(line);
  
          if(limit <= index+1){
              if(onData){
                  rl.pause();
                  var result = lines.slice(0, limit);
                  lines.splice(0, limit);
                  onData(null, result);
                  onData = null;
              }
          }
      });
  
      rl.on('close', function() {
          rl.closed = true;
          if(onData){
              onData(null, lines);
              onData = null;
          }
      });
  
      rl.pause();
      
      return {
          read: getLines,
          close: function(){
              rl.close();
          }
      };
  }
func_code_string: function fileLineReader(filepath, opts){
      if(typeof arguments[0] !== 'string'){
          opts = arguments[0];
          filepath = opts.file || opts.filename || opts.filepath;
      }
  
      filepath = resolve(filepath).fullPath;
  
      opts = opts || {};
      var chunkSize = opts.chunkSize || 1;
      var hasHeader = opts.header || opts.headers || opts.hasHeader;
      var headLine;
      var instream = fs.createReadStream(filepath, opts);
      var outstream = new Stream();
      var rl = readline.createInterface(instream, outstream);
      var onData;
      
      var done;
      instream.on('error', function(err) {
          rl.closed = true;
          rl.close();
          if(done) done(err);
          else throw err;
      });
      
      opts.separator = opts.separator || opts.delimiter;
  
      var lineParser = opts.lineParser || function(line){
          if(!opts.separator) return line;
          return line.split(opts.separator);
      };
  
      var lines = [];
      var lineError;
      var index = -1;
      var limit = 1;
      
      function getLines(numOfLines, cb){
          if(arguments.length === 0) cb = arguments[0];
          if(typeof cb !== 'function') throw new Error('Wrong arguments');
          
          done = cb;
          
          index = index === -1 ? -1 : 0;
          limit = numOfLines || 1;
          var result;
          
          if(lines.length===0) index = -1; // fix - when paused on chunkSize
          if(lines.length >= limit) {
              result = lines.slice(0, limit);
              lines.splice(0,limit);
              return cb(null, result);
          }
          
          if(rl.closed){
              result = lines.slice();
              lines = [];
              return cb(null, result);
          }
          
          onData = cb;
          rl.resume();
      }
  
      rl.on('line', function(line) {
          index++;
  
          line = lineParser(line);
          
          if(headLine){
              var lineWithHeader = {};
              for(var i=0;i<headLine.length;i++){
                  lineWithHeader[ headLine[i] ] = line[i];
              }
              line = lineWithHeader;
          }
          else if(index===0 && hasHeader){
              headLine = line;
              index--;
              return;
          }
  
          lines.push(line);
  
          if(limit <= index+1){
              if(onData){
                  rl.pause();
                  var result = lines.slice(0, limit);
                  lines.splice(0, limit);
                  onData(null, result);
                  onData = null;
              }
          }
      });
  
      rl.on('close', function() {
          rl.closed = true;
          if(onData){
              onData(null, lines);
              onData = null;
          }
      });
  
      rl.pause();
      
      return {
          read: getLines,
          close: function(){
              rl.close();
          }
      };
  }
func_documentation_string: read file by specified amount of lines, parse head line, perfect for CSV-like data files
  @param   {String} file path
  @param   {Object} opts read options and callbacks
  @returns {Readline} nodejs readline interface