public static void main(String[] args) throws FileNotFoundException, ExecutionException, InterruptedException, IOException { 
        int NT = Integer.parseInt(args[0]);
        String inputFile = args[1];
        String outputFile = args[2];
      
        InputReader in = new InputReader(inputFile);
        String fragment = new String();
        long fileSize;
        int byteNumber = 0;
        RandomAccessFile f;
        String currentDoc = new String();
   
        outputDocs = new Vector<ReduceOutput>();
        /*
         * Operatiile de tip map
         */
        Vector<Future<MapOutput>> mapResults = new Vector<Future<MapOutput>>();
        Callable<MapOutput> mWorker;
        Future<MapOutput> mFuture;
        ExecutorService mapPool = Executors.newFixedThreadPool(NT);
        
        for (int i = 0; i < in.ND; i++) {
            currentDoc = in.documents.elementAt(i);
            f = new RandomAccessFile(currentDoc, "r");
            fileSize = f.length();
            f.close();

            /*
             * Citeste cate un fragment si creeaza un MapWorker pentru el
             */
            while(byteNumber < fileSize){
                if(byteNumber + in.D > fileSize){
                    fragment = in.getFragment(byteNumber, (int)fileSize, currentDoc);
                    mWorker = new MapWorker(fragment, currentDoc);
                    mFuture = mapPool.submit(mWorker);
                    mapResults.add(mFuture);
                    break;
                }
                
                fragment = in.getFragment(byteNumber, byteNumber + in.D, currentDoc);
                mWorker = new MapWorker(fragment, currentDoc);
                mFuture = mapPool.submit(mWorker);
                mapResults.add(mFuture);
                
                byteNumber += in.D;
            }
            
            byteNumber = 0;
        }
        mapPool.shutdown();
        while(!mapPool.isTerminated()){}
        
        
        /*
         * Operatiile de tip reduce
         */
        Callable<ReduceOutput> rWorker;
        Future<ReduceOutput> rFuture;
        Vector<MapOutput> reduceInput = new Vector<MapOutput>();
        ExecutorService reducePool = Executors.newFixedThreadPool(NT);
        
        for (int i = 0; i < in.ND; i++) {
            currentDoc = in.documents.elementAt(i);
            for (int j = 0; j < mapResults.size(); j++) {
                if(currentDoc.equals(mapResults.elementAt(j).get().fileName))
                    reduceInput.add(mapResults.elementAt(j).get());
            }
            
            rWorker = new ReduceWorker(reduceInput, in);
            rFuture = reducePool.submit(rWorker);
            reduceInput = new Vector<MapOutput>();
        }
        
        
        reducePool.shutdown();
        while(!reducePool.isTerminated()){}
     
        printResult(in, outputFile);
    }