public void run () {
		ArrayList<Document> listCrawled = DatabaseUtils
				.retrieveAllCrawledObjects (this.store);
		for (Document nextDoc : listCrawled) {
			synchronized (application.crawledDocuments) {
				application.crawledDocuments++;
			}
			CrawlerIndexer.getInstance ().enqueue (nextDoc.getId ());
		}
		log.info ("Master " + this.getName () + " has started");
		for (int i = 0; i < Integer.parseInt (NodeUtils.getInstance ()
				.getValue (Constants.NUM_CRAWLER_THREADS)); i++) {
			threadPool[i] = new Worker (this.hostToQueue, this.qMaster,
					this.frontEndQueue, this.backEndQueues, this.store,
					this.dbUtils, this.dbFolder, this.maximumSize,
					this.disallow, this.terminate, this.flagFirstTime,
					this.application);

			this.terminate.put (threadPool[i], true);
			threadPool[i].start ();
			log.info ("Worker" + threadPool[i].getName () + " has started");
		}
		while (true) {
			try {
				Thread.sleep (10000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace ();
			}
			// System.out.println("Master shutdown "+ isShutDown);
			if (isShutDown) {
				for (int i = 0; i < Integer.parseInt (NodeUtils.getInstance ()
						.getValue (Constants.NUM_CRAWLER_THREADS)); i++) {
					threadPool[i].shutDown ();
					if (threadPool[i].getState () == Thread.State.WAITING) {
						threadPool[i].shutDown();
						threadPool[i].interrupt ();
					}
				}

				for (int i = 0; i < Integer.parseInt (NodeUtils.getInstance ()
						.getValue (Constants.NUM_CRAWLER_THREADS)); i++) {
					try {
						threadPool[i].join ();
					} catch (InterruptedException e) {
						e.printStackTrace ();
					}
				}

				log.info ("Master Thread " + this.getName () + " has stopped");
				System.out.println ("Master Thread " + this.getName ()
						+ " has stopped");
				break;
			}
		}
	}