@Override
	public int run(String[] args) throws Exception {
		if (args.length != 4) {
			System.err.println("Usage: PageRank <input path> <output path> <iterations> <tolerance>") ;
			return -1 ;
		}
		
		FileSystem fs = FileSystem.get(getConf()) ;
		String input = args[1] + File.separator + "previous-pageranks";
		String output = args[1] + File.separator + "current-pageranks" ;
		
		ToolRunner.run(getConf(), new CheckingData(), new String[] { args[0], output } ) ;
		ToolRunner.run(getConf(), new CountPages(), new String[] { output, args[1] + File.separator + "count" } ) ;
		String count = read (fs, args[1] + File.separator + "count") ;
		ToolRunner.run(getConf(), new InitializePageRanks(), new String[] { output, input, count } ) ;
		int i = 0 ;
		while ( i < Integer.parseInt(args[2]) ) {
			ToolRunner.run(getConf(), new DanglingPages(), new String[] { input, args[1] + File.separator + "dangling" } ) ;
			String dangling = read (fs, args[1] + File.separator + "dangling") ;
			ToolRunner.run(getConf(), new UpdatePageRanks(), new String[] { input, output, count, dangling } ) ;
			swap ( fs, new Path(output),  new Path(input) ) ;
			if ( ( i > CHECK_CONVERGENCE_FREQUENCY) && ( i % CHECK_CONVERGENCE_FREQUENCY == 0 ) ) {
				ToolRunner.run(getConf(), new CheckConvergence(), new String[] { input, args[1] + File.separator + "convergence" } ) ;
				double tolerance = Double.parseDouble(read (fs, args[1] + File.separator + "convergence")) ;
				if ( tolerance <= Double.parseDouble(args[3]) ) {
					break ;
				}
			}
			
			if (HTML_TABLE) {
				ToolRunner.run(getConf(), new SortPageRanks(), new String[] { input, args[1] + File.separator + "sorted-pageranks" } ) ;
				BufferedReader in = new BufferedReader(new InputStreamReader(fs.open(new Path(args[1] + File.separator + "sorted-pageranks" + File.separator + "part-00000")))) ;
				PrintWriter out = new PrintWriter(fs.create(new Path(args[1] + File.separator + "sorted-pageranks-" + i + ".dat")).getWrappedStream()) ;
				for (int j = 0 ; j < HTML_TABLE_ROWS ; j++ ) {
					StringTokenizer st = new StringTokenizer(in.readLine()) ;
					out.write(st.nextToken() + "\n") ;
				}
				in.close() ;
				out.close() ;				
			}

			i++ ;
		}
			
		ToolRunner.run(getConf(), new SortPageRanks(), new String[] { input, args[1] + File.separator + "sorted-pageranks" } ) ;
		
		if (HTML_TABLE) {
			ToolRunner.run(getConf(), new HTMLTable(), new String[] { args[1], Integer.toString(HTML_TABLE_ROWS), Integer.toString(i) } ) ;			
		}

		return 0;
	}