public class Preferences {
	private static Logger logger = Logger.getLogger(Preferences.class.getName());

	static PreferenceData prefData;
	
	public Preferences() {
		logger.info("Preferences()");
		//PreferenceData prefData= (PreferenceData) Persister.open(new File("Preference.xml"));
		//getPreferences();
	}
	public static void load() {
		prefData= (PreferenceData) Persister.open(new File("Preference.xml"));
		if (prefData ==null || prefData.preferences==null) {
			prefData= new PreferenceData();
			logger.debug(prefData+";"+prefData.preferences);
			Persister.save(new File("Preference.xml"), (PreferenceData) prefData);
			logger.info("Created Preference.xml");
		}
		getPreferences();
	}
	
	public static HashMap<String, String> getPreferences() {
		if (prefData.preferences == null) {
			prefData.preferences = new HashMap<String, String>();
			logger.info("new prefData.preferences");
		}
		if (!prefData.preferences.containsKey("timings")) {
			prefData.preferences.put("timings", "false");
		}
		if (!prefData.preferences.containsKey("matches")) {
			prefData.preferences.put("matches", "true");
		}
		if (!prefData.preferences.containsKey("stats")) {
			logger.info("stats set to true");
			prefData.preferences.put("stats", "true");
		}
		if (!prefData.preferences.containsKey("chartSize")) {
			prefData.preferences.put("chartSize", "350");
		}
		if (!prefData.preferences.containsKey("lastPath")) {
			prefData.preferences.put("lastPath", ".");
		}
		if (!prefData.preferences.containsKey("ThreadPool_SourceGroup")) {
			prefData.preferences.put("ThreadPool_SourceGroup", "4");
		}
		if (!prefData.preferences.containsKey("ThreadPool_MineProcessor")) {
			prefData.preferences.put("ThreadPool_MineProcessor", "8");
		}
		if (!prefData.preferences.containsKey("ThreadPool_ProcessorByGroup")) {
			prefData.preferences.put("ThreadPool_ProcessorByGroup", "2");
		}
		if (!prefData.preferences.containsKey("editorCommand")) {
			prefData.preferences.put("editorCommand", "gvim -R +$line \"$file\"");
		}
		if (!prefData.preferences.containsKey("gatherstats")) {
			prefData.preferences.put("gatherstats", "true");
		}
		if (!prefData.preferences.containsKey("gatherevents")) {
			prefData.preferences.put("gatherevents", "true");
		}
		if (!prefData.preferences.containsKey("gatherreports")) {
			prefData.preferences.put("gatherreports", "true");
		}
		if (!prefData.preferences.containsKey("eventsAsDots")) {
			prefData.preferences.put("eventsAsDots", "true");
		}
		if (!prefData.preferences.containsKey("MiningFileChunk")) {
			prefData.preferences.put("MiningFileChunk", "1000");
		}		
		if (!prefData.preferences.containsKey("ForceSourceDateFormat")) {
			prefData.preferences.put("ForceSourceDateFormat", "false");
		}				
		
		
		
		return prefData.preferences;
	}
	
	public static void setPreference(String key, String value) {
		prefData.preferences.put(key, value);
		logger.debug(prefData.preferences);
		Persister.save(new File("Preference.xml"), (PreferenceData) prefData);
	}

	public static String getPreference(String key) {
		return getPreferences().get(key);
	}
	
	public static boolean isStats() {
		return Boolean.parseBoolean(getPreference("stats"));
	}

	public void setStats(boolean stats) {
		setPreference("stats", Boolean.toString(stats));
	}

	public static boolean isTimings() {
		return Boolean.parseBoolean(getPreference("timings"));
	}

	public void setTimings(boolean timings) {
		setPreference("timings", Boolean.toString(timings));
	}
	public static boolean isMatches() {
		return Boolean.parseBoolean(getPreference("matches"));
	}
	
	public void setMatches(boolean matches) {
		setPreference("matches", Boolean.toString(matches));
	}
	
	public static boolean getBooleanPreference(String key){
		// TBD : implement a cache 
		return Boolean.parseBoolean(getPreferences().get(key));
	}

	public static void persist() {
		logger.debug(prefData);
		Persister.save(new File("Preference.xml"), (PreferenceData) prefData);
		// TODO Auto-generated method stub
		
	}

} public class Repository {
	private static Logger logger = Logger.getLogger(DataMiner.class.getName());
	private ArrayList<Recording> recordings;
	private ArrayList<Source> sources;
	private String baseSourcePath;
	private ArrayList<DateFormat> dates;
	private boolean recursiveMode;
	private boolean onlyMatches;
	private boolean stats; // unused
	private boolean timings; // unused
	private HashMap<String, String> preferences;

	public Repository() {
		preferences = new HashMap<String, String>();
		preferences.put("timings", "false");
		preferences.put("stats", "true");
		preferences.put("chartSize", "350");
		preferences.put("ThreadPool_Group", "4");
		preferences.put("ThreadPool_File", "8");
		preferences.put("editorCommand", "gvim -R +$line $file");
		preferences.put("gatherstats", "true");
		preferences.put("gatherevents", "true");
		preferences.put("gatherreports", "true");
		recordings = new ArrayList<Recording>();
		dates = new ArrayList<DateFormat>();
		sources = new ArrayList<Source>();
		recursiveMode = false;
		// logger.info("repository ArrayList initialized");
	}

	public boolean isRecursiveMode() {
		return recursiveMode;
	}

	public void setPreference(String key, String value) {
		preferences.put(key, value);
	}

	public String getPreference(String key) {
		return getPreferences().get(key);
	}

	public void setRecursiveMode(boolean recursiveMode) {
		// logger.info("recursive mode is :"+recursiveMode);
		this.recursiveMode = recursiveMode;
	}

	public ArrayList<Source> getSources() {
		return sources;
	}

	public Source getSource(String name) {
		Iterator sourceIterator = sources.iterator();
		int cnt = 0;
		while (sourceIterator.hasNext()) {
			Source src = (Source) sourceIterator.next();
			if (src.getSourceName() == name) {
				return src;
			}
		}
		return (Source) null;
	}

	public void setSources(ArrayList<Source> sources) {
		this.sources = sources;
	}

	public void addSource(Source s) {
		if (sources == null) {
			sources = new ArrayList<Source>();
		}
		sources.add(s);
	}

	public void deleteSource(int id) {
		sources.remove(id);
	}

	public Source getSource(int id) {
		return sources.get(id);
	}

	public void updateSource(int id, String txtName, String txtRegularExp, Boolean active) {
		sources.get(id).setSourceName(txtName);
		sources.get(id).setSourcePattern(txtRegularExp);
		sources.get(id).setActive(active);
	}

	public ArrayList<Recording> getRecordings() {
		// logger.info(xstream.toXML(recordings));
		return recordings;
	}

	public ArrayList<Recording> getRecordings(Class _class, boolean onlyActive) {

		ArrayList<Recording> statRecordingArrayList = new ArrayList<Recording>();
		Iterator recordingIterator = recordings.iterator();
		int cnt = 0;
		while (recordingIterator.hasNext()) {
			Recording r = (Recording) recordingIterator.next();
			if (r.getClass().equals(_class)) { 
				if (onlyActive){
					if (r.getIsActive())
					statRecordingArrayList.add(r);	
				} else {
				statRecordingArrayList.add(r);
				}
			}
		}

		return (ArrayList<Recording>) statRecordingArrayList;
	}


	public ArrayList getReportRecordings(MineResultSet mineResultSet1, boolean b) {
		ArrayList<Recording> temp = new ArrayList<Recording>();
		ArrayList<Recording> returned= new ArrayList<Recording>();		
		Iterator<Map<Recording, Map<List<Object>, Long>>> it1 = mineResultSet1.getOccurenceReport().values().iterator();
		while (it1.hasNext()){
			Iterator test = (Iterator) it1.next().keySet().iterator();
			while (test.hasNext())
			{
			temp.add((Recording) test.next());
			}
		}
		
		Iterator<Map<Recording, Map<List<Object>, Double>>> it2 =mineResultSet1.getSumReport().values().iterator();
		while (it2.hasNext()){
			Iterator test = (Iterator) it2.next().keySet().iterator();
			while (test.hasNext())
			{
			temp.add((Recording) test.next());
			}
		}
		
		Iterator<Map<Recording, SortedMap<Double, List<Object>>>> it3 =mineResultSet1.getTop100Report().values().iterator();
		while (it3.hasNext()){
			Iterator test = (Iterator) it3.next().keySet().iterator();
			while (test.hasNext())
			{
			temp.add((Recording) test.next());
			}
		}
		
		ArrayList<Recording> aL = getRecordings(ReportRecording.class, b);
		Iterator ite = aL.iterator();
		while (ite.hasNext()){
			Recording rec= (Recording) ite.next();
			if (temp.contains(rec))	{
			returned.add(rec);	
			}
		}
		return returned;
	}
	
	
	public Recording getRecording(Class _class, int id, boolean onlyActive) {
		return getRecordings(_class,onlyActive).get(id);
	}

	public HashMap<String, String> getPreferences() {
		if (preferences == null) {
			preferences = new HashMap<String, String>();
			logger.info("new preferences");
		}
		if (!preferences.containsKey("timings")) {
			preferences.put("timings", "false");
		}

		if (!preferences.containsKey("stats")) {
			logger.info("stats set to true");
			preferences.put("stats", "true");
		}

		if (!preferences.containsKey("chartSize")) {
			preferences.put("chartSize", "350");
		}

		if (!preferences.containsKey("ThreadPool_Group")) {
			preferences.put("ThreadPool_Group", "4");
		}
		if (!preferences.containsKey("ThreadPool_File")) {
			preferences.put("ThreadPool_File", "8");
		}
		if (!preferences.containsKey("editorCommand")) {
			preferences.put("editorCommand", "gvim -R +$line $file");
		}
		
		return preferences;
	}

	public void addRecording(Recording r) {
		recordings.add(r);
		// logger.info(xstream.toXML(recordings));<
	}

	public int getRecordingCount() {
		return recordings.size();
	}

	public void deleteRecording(int id) {
		recordings.remove(id);
		ArrayList<Source> sources= this.getSources();
		Iterator<Source> ite=sources.iterator();
		while (ite.hasNext()){
			Source src=(Source) ite.next();
			src.removeActiveRecording(recordings.get(id));
		}
	}

	public Recording getRecording(int id) {
		return recordings.get(id);
	}

	public Recording getRecording(String _id) {
		Iterator recordingIterator = recordings.iterator();
		Recording recReturn = null; 
		int cnt = 0;
		while (recordingIterator.hasNext()) {
			Recording r = (Recording) recordingIterator.next();
			if (r.getId() == _id) {
				recReturn = r;
			}
		}
		return recReturn;
	}

	public void duplicateRecording(int id) {
		Recording newRecording = recordings.get(id).duplicate();
		this.addRecording(newRecording);
		ArrayList<Source> sources= this.getSources();
		Iterator<Source> ite=sources.iterator();
		if (!MetadataRecording.class.isInstance(recordings.get(id))){
		while (ite.hasNext()){
			Source src=(Source) ite.next();
			if (src.isActiveRecordingOnSource(recordings.get(id))){
				src.toggleActiveRecording(newRecording);
			}
		}}
	}

	public void update(Repository repo) {
		recordings = repo.getRecordings();
	}

	public void save(File file) {

		FileOutputStream fos = null;
		try {
			String xml = new XStream(new StaxDriver()).toXML(recordings);
			fos = new FileOutputStream(file);
			// fos.write("<?xml version=\"1.0\"?>".getBytes("UTF-8"));
			byte[] bytes = xml.getBytes("UTF-8");
			fos.write(bytes);

		} catch (Exception e) {
			System.err.println("Error in XML Write: " + e.getMessage());
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void open(File file) {
		// XStream xstream = new XStream(new StaxDriver());
		FileOutputStream fos = null;
		try {
			recordings = (ArrayList<Recording>) new XStream(new StaxDriver()).fromXML(file);
			/*
			 * fos = new FileOutputStream(file);
			 * 
			 * byte[] bytes = xml.getBytes("UTF-8"); fos.write(bytes);
			 */
			logger.info(new XStream(new StaxDriver()).toXML(recordings));
		} catch (Exception e) {
			System.err.println("Error in XML Write: " + e.getMessage());
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public void setRecordings(ArrayList recordings) {
		this.recordings = recordings;
	}

	public void save() {

	}

	public String getBaseSourcePath() {
		return baseSourcePath;
	}

	public void setBaseSourcePath(String baseSourcePath) {
		this.baseSourcePath = baseSourcePath;
	}

	public ArrayList<DateFormat> getDates() {
		return dates;
	}

	public void setDates(ArrayList<DateFormat> hm) {
		dates = hm;
	}

	public void addDateFormat(DateFormat df) {
		if (dates == null) {
			dates = new ArrayList<DateFormat>();
		}
		dates.add(df);
		// logger.info(xstream.toXML(recordings));
	}

	public void deleteDateFormat(int id) {
		dates.remove(id);
	}

	public DateFormat getDateFormat(int id) {
		return dates.get(id);
	}

	public DateFormat getDateFormat(String id) {
		Iterator dateFormatIterator = dates.iterator();
		int cnt = 0;
		while (dateFormatIterator.hasNext()) {
			DateFormat df = (DateFormat) dateFormatIterator.next();
			if (df.getId() == id) {
				return df;
			}
		}
		return (DateFormat) null;
	}

	public void setOnlyMatches(boolean selected) {
		onlyMatches = selected;

	}

	public boolean isOnlyMatches() {
		return onlyMatches;
	}

	public boolean isStats() {
		return Boolean.parseBoolean(getPreference("stats"));
	}

	public void setStats(boolean stats) {
		setPreference("stats", Boolean.toString(stats));
	}

	public boolean isTimings() {
		return Boolean.parseBoolean(getPreference("timings"));
	}

	public void setTimings(boolean timings) {
		setPreference("timings", Boolean.toString(timings));
	}

} public class Source implements Comparable{
	private static Logger logger = Logger.getLogger(Source.class.getName());
	private String sourceName;
	private String sourcePattern;
	private DateFormat dateFormat;
	private Boolean active;
	private MetadataRecording activeMetadataRecording;
	private ArrayList<String> selectedRecordingIds;

	public Source(String name, String pattern, DateFormat _dateFormat, Boolean _active) {
		sourceName = name;
		sourcePattern = pattern;
		dateFormat = _dateFormat;
		setActive(_active);
		selectedRecordingIds = new ArrayList<String>();
		logger.info("Source loaded");

	}

	public String getSourcePattern() {
		return sourcePattern;
	}

	public void setSourcePattern(String sourcePattern) {
		this.sourcePattern = sourcePattern;
	}

	public void setActiveMetadata(MetadataRecording _activeMetadataRecording){
		activeMetadataRecording=_activeMetadataRecording;
	}

	public MetadataRecording getActiveMetadata(){
		return activeMetadataRecording;
	}
	
	public void toggleActiveRecording(Recording recording) {
		// logger.info("toggleActiveRecording of "+recording.getName());
		if (selectedRecordingIds.contains(recording.getId())) {
			selectedRecordingIds.remove(recording.getId());
			if (logger.isEnabledFor(Level.TRACE))
				logger.trace("toggleActiveRecording removed " + recording.getName() + " now size " + selectedRecordingIds.size());
		} else {
			selectedRecordingIds.add(recording.getId());
			if (logger.isEnabledFor(Level.TRACE))
				logger.trace("toggleActiveRecording added " + recording.getName() + " now size " + selectedRecordingIds.size());
		}

	}

	public void removeActiveRecording(Recording recording) {
		// logger.info("toggleActiveRecording of "+recording.getName());
		if (selectedRecordingIds.contains(recording.getId())) {
			selectedRecordingIds.remove(recording.getId());
			if (logger.isEnabledFor(Level.TRACE))
				logger.trace("toggleActiveRecording removed " + recording.getName() + " now size " + selectedRecordingIds.size());
		} 
	}
	
	
	
	public Boolean isActiveRecordingOnSource(Recording recording) {
		if (MetadataRecording.class.isInstance(recording)){
				if (getActiveMetadata()!=null && getActiveMetadata()==recording){
					return true;
				}
				else return false;
		}
		// logger.info("***isActiveRecordingOnSource of "+recording.getName());
		Boolean b = false;
		Iterator it = selectedRecordingIds.iterator();
		String recordingId = recording.getId();
		while (it.hasNext()) {
			// String temp=(String)it.next();
			if ((String) it.next() == recordingId) {
				// logger.info("***isActiveRecordingOnSource of "+recording.getName()
				// + " with id: "+ temp);
				b = true;
			}
		}
		return b;
	}

	public String getSourceName() {
		return sourceName;
	}

	public void setSourceName(String sourceName) {
		this.sourceName = sourceName;
	}

	public Boolean getActive() {
		return active;
	}

	public void setActive(Boolean active) {
		this.active = active;
	}

	@Override
	public int compareTo(Object o) {
		String local = getSourceName();
		String remote = ((Source)o).getSourceName();
		//return remote.compareTo(local);
		return local.compareTo(remote);

	}

	public DateFormat getDateFormat() {
		return dateFormat;
	}

	public void setDateFormat(DateFormat dateFormat) {
		this.dateFormat = dateFormat;
	}
} public class ChartData {
	public ArrayList<Source> sourceArrayList;
	public Map<Source, Map<Integer,FileRecord>> sourceFileArrayListMap = new HashMap<Source, Map<Integer,FileRecord>>();
	public Map<Integer,FileRecord> selectedSourceFiles;
	public TimeSeriesCollection dataset = new TimeSeriesCollection();
	public ArrayList<String> disabledSeries= new ArrayList<String>();
	Map<Source, Map<String, ArrayList<FileRecord>>> MapSourceGroupFilesArrayList = new HashMap<Source, Map<String, ArrayList<FileRecord>>>();

	public void setGroupFilesArrayListMap(Source src, Map<String, ArrayList<FileRecord>> sourceFileGroup) {
		MapSourceGroupFilesArrayList.put(src, sourceFileGroup);
		// TODO Auto-generated method stub
	}

	public Map<String, ArrayList<FileRecord>> getGroupFilesMap(Source src) {
		return MapSourceGroupFilesArrayList.get(src);
	}

	public void addDisabledSeries(String name) {
		disabledSeries.add(name);
		
	}

	public void removeDisabledSeries(String name) {
		disabledSeries.remove(name);
		
	}
	
	
} public class DataVault {
	static public MineResultSet mineResultSet;
	private static Logger logger = Logger.getLogger(DataVault.class.getName());
	static private  Map<Recording,ArrayList<String>> recordingMatchedLines = new HashMap<Recording,ArrayList<String>>();
	static private  Map<Recording,ArrayList<String>> recordingUnmatchedLines = new HashMap<Recording,ArrayList<String>>();
	public synchronized static MineResultSet getMineResultSet() {
		return mineResultSet;
	}

	public synchronized static void setMineResultSet(MineResultSet mineResultSet) {
		DataVault.mineResultSet = mineResultSet;
	}

	public DataVault() {
		// TODO Auto-generated constructor stub
	}

	public static String getMatchedLines(Recording rec){
		ArrayList aL=recordingMatchedLines.get(rec);
		String returned="";
		if (aL!=null){
		Iterator ite= aL.iterator();
		
		while (ite.hasNext()){
			returned+=ite.next()+System.getProperty("line.separator");
		}}
		return returned;
	}
	
	public static void addMatchedLines(Recording rec,String line){
		ArrayList<String> al=null;
		if (recordingMatchedLines.get(rec)==null)
				{
			al=new ArrayList<String>();
			recordingMatchedLines.put(rec,al);
				}
		if (recordingMatchedLines.get(rec)!=null ){
			if (recordingMatchedLines.get(rec).size()<5){
				recordingMatchedLines.get(rec).add(line);	
			}}
	//	recordingMatchedLines.put(rec,al);
	}
	
	public static String getUnmatchedLines(Recording rec){
		ArrayList aL=recordingUnmatchedLines.get(rec);

		String returned="";
		if (aL!=null){
			Iterator ite= aL.iterator();
			while (ite.hasNext()){
			returned+=ite.next()+System.getProperty("line.separator");;
		}}
		return returned;
	}
	public static void addUnmatchedLines(Recording rec,String line){
		ArrayList<String> al=null;
		if (recordingUnmatchedLines.get(rec)==null)
				{
			al=new ArrayList<String>();
			recordingUnmatchedLines.put(rec,al);
				}
		if (recordingUnmatchedLines.get(rec)!=null ){
			if (recordingUnmatchedLines.get(rec).size()<5){
				recordingUnmatchedLines.get(rec).add(line);	
			}
			
	//	recordingMatchedLines.put(rec,al);
		}
	}
	
	public static long[] getRecordingStats(String recording) {
		if (mineResultSet == null)
			return null;
		Iterator it = mineResultSet.mineResults.values().iterator();
		long[] tmpArray;
		long[] stats = { 0, 0, 0, 0 };// == new HashMap<String, long[]> ();
		while (it.hasNext()) {
			Map<String, MineResult> map = (Map<String, MineResult>) it.next();
			// logger.info("keys: "+map.keySet());
			// logger.info("Values: "+map.values());
			Iterator it2 = map.values().iterator();
			while (it2.hasNext()) {
				MineResult mr = (MineResult) it2.next();
				Map<String, long[]> tempStatMap = mr.getMatchingStats();
				if (tempStatMap.containsKey(recording)) {
					tmpArray = tempStatMap.get(recording);
					// logger.info(file.getName() + " contains " + arrayBefore);
					// 0-> sum of time for success matching of given
					// recording ; 1-> sum of time for failed
					// matching ; 2-> count of match attempts,
					// 3->count of success attempts
					stats[0] += tmpArray[0];
					stats[1] += tmpArray[1];
					stats[2] += tmpArray[2];
					stats[3] += tmpArray[3];
					// logger.info(file.getName() + " add success to" +
					// rec.getName() + " 0: "+ array[0] + " 1: "+ array[1]+
					// " 2: "+ array[2] +" 3: "+ array[3]);
				}
			}
		}
		return stats;

	}
} public class Miner {
	private static Logger logger = Logger.getLogger(Miner.class.getName());
	private static ExecutorService ThreadPool_MineProcessorWorkers = null;
	private static ExecutorService ThreadPool_SourceGroupWorkers = null;
	static long estimatedTime = 0;
	static long startTime = 0;
	static List<File> listOfFiles = null;
	static ReportData reportData=new ReportData();
	static Thread consumer;

	static final BlockingQueue<ReportItem> reportQueue=new LinkedBlockingQueue<ReportItem>();
	
	public static MineResultSet gatherMineResultSet(ChartData cd, final Repository repo, final MainFrame mainFrame) {
		int ini = Integer.parseInt(Preferences.getPreference("ThreadPool_SourceGroup"));
		logger.debug("gatherMineResultSet parallelism: " + ini);
		ThreadPool_SourceGroupWorkers = Executors.newFixedThreadPool(ini);
		int ini2 =Integer.parseInt(Preferences.getPreference("ThreadPool_MineProcessor"));
		ThreadPool_MineProcessorWorkers = Executors.newFixedThreadPool(ini2);
		Collection<Callable<MineResult>> tasks = new ArrayList<Callable<MineResult>>();
		MineResultSet mineResultSet = new MineResultSet();
		reportData.clear();
		ReportProcessor reportProcessor= new ReportProcessor(reportQueue, reportData);
		consumer = new Thread(reportProcessor);
		consumer.start();
		startTime = System.currentTimeMillis();
		/*
		 * try { cd = DataMiner.gatherSourceData(repo); } catch (Exception e) {
		 * return null; }
		 */

		Iterator<Source> sourceIterator2 = repo.getSources().iterator();
		int progressCount = 0;
		while (sourceIterator2.hasNext()) {
			final Source source = sourceIterator2.next();
			// sourceFiles contains all the matched files for a given source
			if (source.getActive() && source.getActiveMetadata() != null) {
				final Map<Recording, String> recMatch1 = DataMiner.getAllRegexSingleMap(repo, source);
				Iterator<Entry<String, ArrayList<FileRecord>>> it = cd.getGroupFilesMap(source).entrySet().iterator();
				while (it.hasNext()) {
					final Map.Entry<String, ArrayList<FileRecord>> pairs = it.next();
					//testing as a group might have no files
					if (pairs.getValue() != null) {
						progressCount = progressCount + pairs.getValue().size();
						if (logger.isDebugEnabled())
							logger.info("Source:" + source.getSourceName() + ", group: " + pairs.getKey() + " = " + pairs.getValue().toString());
						tasks.add(new Callable<MineResult>() {
							public MineResult call() throws Exception {
								return Miner.mine(pairs.getKey(), pairs.getValue(), repo, source,recMatch1, Preferences.isStats(), Preferences.isTimings(),
										Preferences.isMatches(), mainFrame);
							}

						});
					}

				}
			}
		}
		mainFrame.setMaxProgress(progressCount);
		// logger.info("progressCount "+ progressCount);
		/*
		 * invokeAll blocks until all service requests complete, or a max of
		 * 1000 seconds.
		 */
		List<Future<MineResult>> results = null;
		try {
			results = ThreadPool_SourceGroupWorkers.invokeAll(tasks, 100000, TimeUnit.SECONDS);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (Future<MineResult> f : results) {
			MineResult mineRes = null;
			try {
				// if (mineRes!=null)
				mineRes = f.get();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (mineRes != null) {
				mineResultSet.updateStartDate(mineRes.getStartDate());
				mineResultSet.updateEndDate(mineRes.getEndDate());
				if (!mineResultSet.mineResults.keySet().contains(mineRes.getSource())) {
					mineResultSet.mineResults.put(mineRes.getSource(), new HashMap<String, MineResult>());
				}
				mineResultSet.mineResults.get(mineRes.getSource()).put(mineRes.getSource().getSourceName() + mineRes.getGroup(), mineRes);
			}
		}
		estimatedTime = System.currentTimeMillis() - startTime;
		logger.info("gathering time: " + estimatedTime);
		
		mineResultSet.setOccurenceReport(reportData.occurenceReport);
		mineResultSet.setTop100Report(reportData.top100Report);
		mineResultSet.setSumReport(reportData.sumReport);
		return mineResultSet;

	}

	// handle gathering for ArrayList of file for one source-group
	public static MineResult mine(String group, ArrayList<FileRecord> arrayList, final Repository repo, final Source source, Map<Recording, String> recMatch1, final boolean stats,
			final boolean timings, final boolean matches, final MainFrame mainFrame) {
		// attempt to reduce memory footprint
		BlockingQueue<MineItem> mineQueue=new LinkedBlockingQueue<MineItem>(100);
		MineData mineData=new MineData();
		int ini =Integer.parseInt(Preferences.getPreference("ThreadPool_ProcessorByGroup"));
		ArrayList<MineProcessor> mineProcessorList= new ArrayList<MineProcessor>();
		for (int i=0;i<ini;i++){
			MineProcessor mineProcessor= new MineProcessor(mineQueue,reportQueue, mineData);
			ThreadPool_MineProcessorWorkers.execute(mineProcessor);
			mineProcessorList.add(mineProcessor);
		}
		long mineStartTime =ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
		final int miningChunk = Integer.parseInt(Preferences.getPreference("MiningFileChunk"));
		Date startDate = null;
		Date endDate = null;
		FileReader flstr = null;
		BufferedReader buf1st;
		Matcher matcher = null;
		int optionBlock = 0;
		Map<String, ExtendedTimeSeries> statMap = new HashMap<String, ExtendedTimeSeries>();
		Map<String, ExtendedTimeSeries> eventMap = new HashMap<String, ExtendedTimeSeries>();
		Map<String, long[]> timingStatsMap = new HashMap<String, long[]>();
		Map<String, Map<Date, FileLine>> fileLine = new HashMap<String, Map<Date, FileLine>>();
		//to be improved

		PatternCache patternCache = new PatternCache();
		Iterator<FileRecord> iterator = arrayList.iterator();
		int nbLines = 0;
		while (iterator.hasNext()) {
			final FileRecord fileRecord = (FileRecord) iterator.next();
			ArrayList<String[]> dataBlock = new ArrayList<String[]>(miningChunk);
			try {
				if (logger.isDebugEnabled()) {
					logger.debug("working on file: " + repo.getBaseSourcePath() + " + " + (String) fileRecord.getCompletePath().toString());
				}
				flstr = new FileReader(fileRecord.getCompletePath());
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			buf1st = new BufferedReader(flstr);
			String line;
			optionBlock =0;
			int offset = 0;
			try {
				while ((line = buf1st.readLine()) != null) {
					matcher = null;
					nbLines++;
					if (source.getDateFormat() != null) {
						matcher = patternCache.getPattern((String) ".*(" + (source.getDateFormat().getPattern()) + ").*", false).matcher(line);
					}
					if (matcher == null) {
						dataBlock.add(new String[] { null, line });
					} else if (matcher.matches()) {
						dataBlock.add(new String[] { "date", line });
					} else {
						dataBlock.add(new String[] { null, null });
					}
					if (nbLines == miningChunk) {
						// logger.info("chunkMine called at line" + totaLines);
						final ArrayList<String[]> tempBlock = new ArrayList<String[]>(dataBlock);
						final int offset1 = offset;
						try {
							mineQueue.put(new MineItem(reportQueue,offset1 * miningChunk, fileRecord, tempBlock, recMatch1, repo, source, stats, timings, matches));
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						dataBlock.clear();
						nbLines = 0;
						offset++;			
					}

				}
				if (nbLines > 0) {
					logger.debug("chunkMine rest called at line" + nbLines);
					final ArrayList<String[]> tempBlock = new ArrayList<String[]>(dataBlock);
					final int offset1 = offset;
					try {
						mineQueue.put(new MineItem(reportQueue,offset1 * miningChunk, fileRecord, tempBlock, recMatch1, repo, source, stats, timings, matches));
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					optionBlock=1;
					dataBlock.clear();
					nbLines = 0;
				}
				//increase the number of blocks present in mineData
				int temp=mineData.getBlocks()+offset+optionBlock;
				mineData.setBlocks(temp);
				logger.debug("temp: "+ temp); 
				logger.debug("blocks: "+(mineData.getBlocks()+offset+optionBlock)+ " "+mineData.getBlocks()+" "+optionBlock + " temp: "+temp);
				
				buf1st.close();
				mainFrame.progress();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}


		
		while (mineQueue.peek()!=null ){
			try {
				Thread.sleep (50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		Iterator it22=mineProcessorList.iterator();
		while (it22.hasNext()){
			MineProcessor mp =(MineProcessor) it22.next();
			mp.shutdown();
		}
while (mineData.getBlocks()!= mineData.fileMineResultArray.size()){
	try {
		Thread.sleep (50);
		logger.debug(mineData.fileMineResultArray.size()+" -- "+mineData.getBlocks());
	} catch (InterruptedException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}


		ArrayList<Object[]> fileDates = new ArrayList<Object[]>();
		Iterator<FileMineResult> mapArrayListIterator = mineData.fileMineResultArray.iterator();
		while (mapArrayListIterator.hasNext()) {
			FileMineResult fMR = (FileMineResult) mapArrayListIterator.next();

			if (startDate == null) {
				startDate = fMR.getStartDate();
			}
			if (endDate == null) {
				endDate = fMR.getEndDate();
			}
			if (fMR.getEndDate() != null && fMR.getStartDate() != null) {
				if (fMR.getEndDate().after(endDate)) {
					endDate = fMR.getEndDate();
				} else if (fMR.getStartDate().before(startDate)) {
					startDate = fMR.getStartDate();
				}
				if (logger.isTraceEnabled()) {
					logger.trace("1: " + fMR.getStartDate() + "2: " + fMR.getEndDate() + "3: " + fMR.getFile());
				}
				fileDates.add(new Object[] { fMR.getStartDate(), fMR.getEndDate(), fMR.getFile() });
			}

			Map<String, ExtendedTimeSeries> tempStatMap = fMR.statGroupTimeSeries;
			tempStatMap.entrySet();
			Iterator it = tempStatMap.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry<String, ExtendedTimeSeries> pairs = (Map.Entry<String, ExtendedTimeSeries>) it.next();
				if (!statMap.containsKey(pairs.getKey())) {
					statMap.put(pairs.getKey(), pairs.getValue());
				} else {
					ExtendedTimeSeries ts = statMap.get(pairs.getKey());
					if (stats) {
						int[] array = { pairs.getValue().getStat()[0] + ts.getStat()[0], pairs.getValue().getStat()[1] + ts.getStat()[1] };
						ts.setStat(array);
					}
					ts.getTimeSeries().addAndOrUpdate(pairs.getValue().getTimeSeries());
					statMap.put(pairs.getKey(), ts);
					// logger.info(pairs.getKey());
				}
			}

			Map tempEventMap = fMR.eventGroupTimeSeries;
			tempEventMap.entrySet();
			it = tempEventMap.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry<String, ExtendedTimeSeries> pairs = (Map.Entry<String, ExtendedTimeSeries>) it.next();
				if (!eventMap.containsKey(pairs.getKey())) {
					eventMap.put(pairs.getKey(), pairs.getValue());
				} else {
					ExtendedTimeSeries ts = eventMap.get(pairs.getKey());
					if (stats) {
						int[] array = { pairs.getValue().getStat()[0] + ts.getStat()[0], pairs.getValue().getStat()[1] + ts.getStat()[1] };
						ts.setStat(array);
					}
					ts.getTimeSeries().addAndOrUpdate(pairs.getValue().getTimeSeries());
					eventMap.put(pairs.getKey(), ts);
				}
			}

			it = fMR.matchingStats.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry<String, long[]> pairs = (Map.Entry<String, long[]>) it.next();
				if (!timingStatsMap.containsKey(pairs.getKey())) {
					timingStatsMap.put(pairs.getKey(), pairs.getValue());
				} else {
					long[] array = timingStatsMap.get(pairs.getKey());
					// 0-> sum of time for success matching of given
					// recording ; 1-> sum of time for failed
					// matching ; 2-> count of match attempts,
					// 3->count of success attempts
					long[] array2 = { pairs.getValue()[0] + array[0], pairs.getValue()[1] + array[1], pairs.getValue()[2] + array[2],
							pairs.getValue()[3] + array[3] };
					timingStatsMap.put(pairs.getKey(), array2);
				}
			}
			it = fMR.fileLineDateMap.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry<String, Map<Date, FileLine>> pairs = (Map.Entry<String, Map<Date, FileLine>>) it.next();
				if (logger.isTraceEnabled()) {
					logger.trace("Entry<String,Map<Date, FileLine>> : " + pairs);
				}
				if (!fileLine.containsKey(pairs.getKey())) {
					fileLine.put(pairs.getKey(), pairs.getValue());
					if (logger.isTraceEnabled()) {
						logger.trace("groupFileLineMap.put " + pairs.getKey() + " -> " + pairs.getValue());
					}
				} else {
					Map<Date, FileLine> ts = fileLine.get(pairs.getKey());
					Map<Date, FileLine> newDateFileLineEntries = pairs.getValue();
					Iterator it2 = newDateFileLineEntries.entrySet().iterator();
					while (it2.hasNext()) {
						Map.Entry<Date, FileLine> pairs2 = (Map.Entry<Date, FileLine>) it2.next();
						fileLine.get(pairs.getKey()).put(pairs2.getKey(), pairs2.getValue());
						if (logger.isTraceEnabled()) {
							logger.trace("groupFileLineMap.put " + pairs2.getKey() + " -> " + pairs2.getValue().getFileId() + ":"
									+ pairs2.getValue().getLineNumber());
						}
					}
				}

			}

		}
		
		long postMineStartTime = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
		logger.info((postMineStartTime - mineStartTime)/1000000+"ms for source " + source.getSourceName() + " on group " + group);
		FileMineResultSet fMRS = new FileMineResultSet(fileDates, statMap, eventMap, timingStatsMap, fileLine, startDate, endDate);
		return new MineResult(group, fMRS, arrayList, repo, source);
	}

	
} public class GraphPanel extends JPanel {
	private Date minimumDate;
	private Date maximumDate;
	private static Logger logger = Logger.getLogger(DataMiner.class.getName());
	private JScrollPane scrollPane;
	private JPanel panel;
	private JPanel panelTop;
	private JPanel panelTopOptions;
	private JPanel panel_1;
	private Repository repo;
	String htmlStr = "<html>";
	private Color[] colors = { new Color(65, 90, 220), new Color(70, 200, 62), new Color(243, 214, 23), new Color(255, 40, 40),
			new Color(0, 205, 205), Color.magenta, Color.orange, Color.pink, new Color(65, 90, 220), new Color(107, 255, 102), new Color(0, 178, 238),
			new Color(60, 179, 113),new Color(179,60 , 113),new Color(179,113, 60 ),new Color(70, 62, 200), new Color(255,171, 130 ), new Color( 40, 255,40),
			new Color(65,171,93),new Color(239,59,44), new Color(65,182,196),new Color(254,178,76),new Color(180,180,180),new Color(93,65,171),Color.blue};
	private Color[] colors2 = { 
			new Color(239,59,44), 
			new Color(83,65,171),
			new Color(44, 117, 255),
			new Color( 40, 170,40),
			Color.ORANGE, 
			Color.blue,
			new Color(65,171,93),
			new Color(70, 62, 200),
			new Color(179,60 , 113),
			new Color(179,113, 60 ),
			new Color(65,182,196),
			new Color(255,171, 130 ),
			Color.pink, 
			new Color(254,178,76),
			new Color(65, 90, 220), 
			new Color(70, 200, 62), 
			new Color(171, 130, 255), 
			new Color(255, 40, 40),
			new Color(0, 205, 205),
			new Color(65, 90, 220), 
			new Color(107, 255, 102), 
			new Color(0, 178, 238),
			new Color(60, 179, 113),
			new Color(180,180,180),};
	//private Color[] colors2= colors.clone();

	// private Color[] colors = { new Color(65,171,93),new Color(254,196,79),new
	// Color(65,171,93), new Color(239,59,44), new Color(65,182,196),new
	// Color(5,112,176), new Color(254,178,76),Color.blue, new Color(255, 40,
	// 40), new Color(65, 90, 220), new Color(70, 255, 62), Color.magenta,
	// Color.orange, Color.pink,
	// new Color(65, 90, 220), new Color(107, 255, 102) };
	private HashMap<String, Boolean> groupCheckBox = new HashMap<String, Boolean>();
	MineResultSet mineResultSet;
	ChartData cd;
	JSpinner startDateJSpinner;
	JSpinner endDateJSPinner;

	long estimatedTime = 0;
	long startTime = 0;

//	XYPlot plot = null;
	JFreeChart chart = null;
	final StandardChartTheme chartTheme = (StandardChartTheme) org.jfree.chart.StandardChartTheme.createJFreeTheme();
	final Font oldSmallFont = chartTheme.getSmallFont();

	final DecimalFormat form = new DecimalFormat("#,##0.00");
	//ArrayList<String> disabledSeries;
	private JPanel panel_2;
	// new DecimalFormat("00.0");
	static MainFrame mainFrame1;
	/**
	 * Create the panel.
	 * 
	 * @param panel_2
	 */

	public GraphPanel(final Repository repo, final JPanel panel_2, final MineResultSet mineResultSet1, final ChartData cd1, final MainFrame _mainFrame) {
		this.repo=repo;
		this.panel_2=panel_2;
		mineResultSet=mineResultSet1;
		cd=cd1;
		mainFrame1=_mainFrame;
		init();
	}
	
	public void init(){
		setLayout(new BorderLayout(0, 0));
		startTime = System.currentTimeMillis();		
		panelTop= new JPanel(new BorderLayout());
		panel_1 = new JPanel(new WrapLayout());
		panelTopOptions = new JPanel(new WrapLayout());
		panelTop.add(panelTopOptions,BorderLayout.EAST);
		JCheckBox chckbxShowChecks = new JCheckBox("Controls");
		chckbxShowChecks.setFont(new Font("Dialog", Font.PLAIN, 11));
		chckbxShowChecks.setSelected(true);	
		JCheckBox chckbxActiveOnly = new JCheckBox("Active only");
		chckbxActiveOnly.setFont(new Font("Dialog", Font.PLAIN, 11));
		chckbxActiveOnly.setSelected(false);				
		JSeparator separator = new JSeparator(SwingConstants.VERTICAL);
		separator.setToolTipText("");
		panelTopOptions.add(separator);
		panelTopOptions.add(chckbxShowChecks);
		panelTopOptions.add(chckbxActiveOnly);
		chckbxShowChecks.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Component[] comp=panel.getComponents();
				int i=0;
				while (i<comp.length-1){
					if (comp[i].getClass().equals(JPanel.class)){
						if (((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(1).getClass().equals(JPanel.class)){			
						((JPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(1)).setVisible(! ((JPanel) ((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(1)).isVisible());
					}}
					i++;
				}
				
			}
		});
		chckbxActiveOnly.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Component[] comp=panel.getComponents();
				int i=0;
				while (i<comp.length-1){
					if (comp[i].getClass().equals(JPanel.class)){
						if (((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(1).getClass().equals(JPanel.class)){	
						Component[] comp2=((JPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(1)).getComponents();
						int i3=0;
						while (i3<comp2.length){;
							if ( !((JCheckBox)comp2[i3]).isSelected()){
								((JCheckBox)comp2[i3]).setVisible(!((JCheckBox)comp2[i3]).isVisible());
							}
							i3++;
							}
					}}
					i++;
				}
				
			}
		});
		
		panelTop.add(panel_1,BorderLayout.CENTER);
		add(panelTop, BorderLayout.NORTH);
		
		//DataVault.mineResultSet = mineResultSet;
		panel = new JPanel();
		if (mineResultSet.mineResults.isEmpty()) {
			logger.info("mineResultSet null");
			panel.add(new JLabel(" No Data "), BorderLayout.CENTER);
		} else {
			startDateJSpinner = (JSpinner) panel_2.getComponent(2);
			endDateJSPinner = (JSpinner) panel_2.getComponent(3);
			minimumDate = mineResultSet.getStartDate();
			maximumDate = mineResultSet.getEndDate();
			if (minimumDate != null)
				startDateJSpinner.setValue(minimumDate);
			if (maximumDate != null)
				endDateJSPinner.setValue(maximumDate);
			scrollPane = new JScrollPane(panel);
			scrollPane.getVerticalScrollBar().setUnitIncrement(16);
			loadGroupCheckbox(panel_2);
			load(panel_2);
		}

	}

	public void resetTimePeriod(JPanel panel_2) {
		startDateJSpinner = (JSpinner) panel_2.getComponent(2);
		endDateJSPinner = (JSpinner) panel_2.getComponent(3);
		minimumDate = mineResultSet.getStartDate();
		maximumDate = mineResultSet.getEndDate();
		if (minimumDate != null)
			startDateJSpinner.setValue(minimumDate);
		if (maximumDate != null)
			endDateJSPinner.setValue(maximumDate);
	}

	public void loadGroupCheckbox(final JPanel panel_2){
		panel_1.removeAll();
		//Iterator mineResultSetIterator = mineResultSet.mineResults.entrySet().iterator();
		
		Map<Source, Map<String, MineResult>> treeMap=new TreeMap<Source, Map<String, MineResult>>(mineResultSet.mineResults) ;
		Iterator mineResultSetIterator = treeMap.entrySet().iterator();
		
		logger.debug("mineResultSet size: " + mineResultSet.mineResults.size());
		while (mineResultSetIterator.hasNext()) {
			
			int groupCount=0;
			int totalGroupCount=0;
			Map.Entry pairs = (Map.Entry) mineResultSetIterator.next();
			Map mrArrayList = (Map<String, MineResult>) pairs.getValue();
			
			ArrayList<String> mineResultGroup = new ArrayList<String>(mrArrayList.keySet());
			Collections.sort(mineResultGroup, new AlphanumComparator());
			
			Iterator mrArrayListIterator = mineResultGroup.iterator();
			while (mrArrayListIterator.hasNext()) {
				String key = (String) mrArrayListIterator.next();
				final MineResult mr = (MineResult) mrArrayList.get(key);
				Map<String, ExtendedTimeSeries> statMap = mr.getStatTimeseriesMap();
				Map<String, ExtendedTimeSeries> eventMap = mr.getEventTimeseriesMap();
				if (!statMap.entrySet().isEmpty() || !eventMap.entrySet().isEmpty()) {
				if (mr.getStartDate() != null && mr.getEndDate() != null) {
					if ((mr.getStartDate().before((Date) endDateJSPinner.getValue())) && (mr.getEndDate().after((Date) startDateJSpinner.getValue()))) {
						groupCount++;
						}
					}}
			}
			Iterator mrArrayListIterator2 = mineResultGroup.iterator();
			while (mrArrayListIterator2.hasNext()) {
				String key = (String) mrArrayListIterator2.next();
				final MineResult mr = (MineResult) mrArrayList.get(key);
				Map<String, ExtendedTimeSeries> statMap = mr.getStatTimeseriesMap();
				Map<String, ExtendedTimeSeries> eventMap = mr.getEventTimeseriesMap();
				if (!statMap.entrySet().isEmpty() || !eventMap.entrySet().isEmpty()) {
				if (mr.getStartDate() != null && mr.getEndDate() != null) {
					if ((mr.getStartDate().before((Date) maximumDate)) && (mr.getEndDate().after((Date) minimumDate))) {
						totalGroupCount++;
						}
					}}
			}
			boolean selected=true;
			if (groupCheckBox.containsKey(((Source)pairs.getKey()).getSourceName())){
				selected=groupCheckBox.get(((Source)pairs.getKey()).getSourceName());
			} else {
				groupCheckBox.put(((Source)pairs.getKey()).getSourceName(),selected);
			}
			
			JCheckBox chckbxGroup = new JCheckBox(((Source)pairs.getKey()).getSourceName()+"("+groupCount+"/"+totalGroupCount+")");
			chckbxGroup.setFont(new Font("Dialog", Font.BOLD, 11));
			chckbxGroup.setSelected(selected);				
			panel_1.add(chckbxGroup);
			chckbxGroup.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					JCheckBox chkBox= ((JCheckBox)e.getSource());
					groupCheckBox.put((String)chkBox.getText().substring(0, ((String)chkBox.getText()).indexOf("(")),!groupCheckBox.get((String)chkBox.getText().substring(0, ((String)chkBox.getText()).indexOf("("))));
					loadGroupCheckbox(panel_2);
					load(panel_2);
					//logger.info("checkBox:"+ chkBox.getText()+","+chkBox.isSelected()+","+groupCheckBox);
					//logger.info("checkBox2:"+((String)chkBox.getText())+", "+((String)chkBox.getText()).indexOf("(")+", "+groupCheckBox.get((String)chkBox.getText().substring(0, ((String)chkBox.getText()).indexOf("(")))); 
				}
			});
		}
	}
	
	public void load(JPanel panel_2) {
		startDateJSpinner = (JSpinner) panel_2.getComponent(2);
		endDateJSPinner = (JSpinner) panel_2.getComponent(3);
		// scrollPane.setV
		panel.removeAll();
		Dimension panelSize = this.getSize();
		add(scrollPane, BorderLayout.CENTER);
		panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
		// scrollPane.set trying to replace scroll where it was
		JCheckBox relativeCheckBox = (JCheckBox) panel_2.getComponent(5);
		startTime = System.currentTimeMillis();
		Map<Source, Map<String, MineResult>> treeMap=new TreeMap<Source, Map<String, MineResult>>(mineResultSet.mineResults) ;
		Iterator mineResultSetIterator = treeMap.entrySet().iterator();
		int ite=0;
		logger.debug("mineResultSet size: " + mineResultSet.mineResults.size());

		while (mineResultSetIterator.hasNext()) {
			ColorCache eventColorCache = new ColorCache(colors2);
			ColorCache statColorCache = new ColorCache(colors);
			final Map.Entry pairs = (Map.Entry) mineResultSetIterator.next();
			logger.debug("mineResultSet key/source: " + ((Source)pairs.getKey()).getSourceName());
			JCheckBox checkBox=(JCheckBox)panel_1.getComponent(ite++);
			logger.debug("checkbox: "+checkBox.getText()+", "+ checkBox.isSelected() );
			if (checkBox.isSelected()){
				
			Map mrArrayList = (Map<String, MineResult>) pairs.getValue();
			ArrayList<String> mineResultGroup = new ArrayList<String>();
			Set<String> mrss = mrArrayList.keySet();
			
			mineResultGroup.addAll(mrss);
			Collections.sort(mineResultGroup, new AlphanumComparator());
			Iterator mrArrayListIterator = mineResultGroup.iterator();
			while (mrArrayListIterator.hasNext()) {

				String key = (String) mrArrayListIterator.next();
				logger.debug(key);
				final MineResult mr = (MineResult) mrArrayList.get(key);
				Map<String, ExtendedTimeSeries> statMap = mr.getStatTimeseriesMap();
				Map<String, ExtendedTimeSeries> eventMap = mr.getEventTimeseriesMap();
				// logger.info("mineResultSet hash size: "
				// +mr.getTimeseriesMap().size());
				// logger.info("mineResultSet hash content: " +
				// mr.getStatTimeseriesMap());
				logger.debug("mineResultSet mr.getStartDate(): " + mr.getStartDate() + " mineResultSet mr.getEndDate(): " + mr.getEndDate());
				logger.debug("mineResultSet (Date)jsp.getValue(): " + (Date) startDateJSpinner.getValue());
				logger.debug("mineResultSet (Date)jsp2.getValue(): " + (Date) endDateJSPinner.getValue());
				if (mr.getStartDate() != null && mr.getEndDate() != null) {
					if ((mr.getStartDate().before((Date) endDateJSPinner.getValue())) && (mr.getEndDate().after((Date) startDateJSpinner.getValue()))) {
						
						ArrayList<String> mineResultGroup2 = new ArrayList<String>();
						Set<String> mrss2 = statMap.keySet();
						mineResultGroup2.addAll(mrss2);
						Collections.sort(mineResultGroup2, new AlphanumComparator());
						Iterator statMapIterator = mineResultGroup2.iterator();
						
						if (!statMap.entrySet().isEmpty() || !eventMap.entrySet().isEmpty()) {
							JPanel checkboxPanel = new JPanel(new WrapLayout());
							checkboxPanel.setBackground(Color.white);
							int count = 1;
							int countEvent = 1;
							int countStat= 1;
							chart = ChartFactory.createXYAreaChart(// Title
									"",// +
									null, // X-Axis
									// label
									null, // Y-Axis label
									null, // Dataset
									PlotOrientation.VERTICAL, false, // Show
																		// legend
									true, // tooltips
									false // url
									);
			//				TextTitle my_Chart_title = new TextTitle(mr.getSourceID() + " " + mr.getGroup(), new Font("Verdana", Font.BOLD, 17));
							final DateAxis domainAxis1 = new DateAxis();
							domainAxis1.setTickLabelsVisible(true);
							logger.debug("getRange: " + domainAxis1.getRange());
							if (relativeCheckBox.isSelected()) {
								domainAxis1.setRange((Date) startDateJSpinner.getValue(), (Date) endDateJSPinner.getValue());
							} else {
								Date startDate = mr.getStartDate();
								Date endDate = mr.getEndDate();
								if (mr.getStartDate().before((Date) startDateJSpinner.getValue())) {
									startDate = (Date) startDateJSpinner.getValue();
									logger.debug("setMinimumDate: " + (Date) startDateJSpinner.getValue());
								}
								if (mr.getEndDate().after((Date) endDateJSPinner.getValue())) {
									endDate = (Date) endDateJSPinner.getValue();
									logger.debug("setMaximumDate: " + (Date) endDateJSPinner.getValue());
								}
								if (startDate.before(endDate)) {
									domainAxis1.setRange(startDate, endDate);
								}
							}
							XYToolTipGenerator tt1 = new XYToolTipGenerator() {
								public String generateToolTip(XYDataset dataset, int series, int item) {
									StringBuffer sb = new StringBuffer();
									Number x= dataset.getX(series, item);
									FastDateFormat sdf = FastDateFormat.getInstance("dd-MMM-yyyy HH:mm:ss");
									sb.append(htmlStr);
									if (x != null) {
										sb.append((sdf.format(x)));
										sb.append("<br>");
										sb.append(dataset.getSeriesKey(series).toString());
										sb.append(": ");
										sb.append(form.format(dataset.getYValue(0, item)) );
										if (mr.getFileLineForDate(new Date(x.longValue()),dataset.getSeriesKey(series).toString())!=null){
											sb.append("<p style='color:#0000FF;'>");
											sb.append(cd.sourceFileArrayListMap.get(pairs.getKey()).get(mr.getFileLineForDate(new Date(x.longValue()),
												dataset.getSeriesKey(series).toString()).getFileId()).getFile().getName());
											sb.append(":");
											sb.append(mr.getFileLineForDate(new Date(x.longValue()),dataset.getSeriesKey(series).toString()).getLineNumber());
											sb.append("</p>");
										
										}
									}
									return sb.toString();
								}
							};

							XYPlot plot1 = (XYPlot) chart.getXYPlot();
							ValueAxis range = plot1.getRangeAxis();
							range.setVisible(false);
							final ValueAxis domainAxis = domainAxis1;
							domainAxis.setLowerMargin(0.0);
							domainAxis.setUpperMargin(0.0);
							plot1.setDomainAxis(0,domainAxis);
							plot1.setDomainCrosshairVisible(true);
							plot1.setRangeCrosshairVisible(true);
							plot1.setOutlineStroke(new BasicStroke((float) 1));
					//		plot1.setOutlinePaint(Color.BLACK);
							plot1.mapDatasetToDomainAxis(0, 1);

							Iterator eventMapIterator = eventMap.entrySet().iterator();
							while (eventMapIterator.hasNext()) {

								TimeSeriesCollection dataset = new TimeSeriesCollection();
								Map.Entry me = (Map.Entry) eventMapIterator.next();
								ExtendedTimeSeries ts = (ExtendedTimeSeries) me.getValue();
								if (((RecordingItem)ts.getRecordingItem()).getProcessingType().toString().equals("occurrences")){
								// if (dataset.getEndXValue(series, item))
								if (((ExtendedTimeSeries) me.getValue()).getTimeSeries().getMaxY() > 0)
									dataset.addSeries(((ExtendedTimeSeries) me.getValue()).getTimeSeries());

								logger.debug("mineResultSet group: " + mr.getGroup() + ", key: " + me.getKey() + " nb records: "
										+ ((ExtendedTimeSeries) me.getValue()).getTimeSeries().getItemCount());
								logger.debug("mineResultSet hash content: " + mr.getEventTimeseriesMap());
								logger.debug("(((TimeSeries) me.getValue()).getMaxY(): " + (((ExtendedTimeSeries) me.getValue()).getTimeSeries().getMaxY()));
								logger.debug("(((TimeSeries) me.getValue()).getMinY(): " + (((ExtendedTimeSeries) me.getValue()).getTimeSeries().getMinY()));


								// axis4.setRange(new Range(((TimeSeries)
								// axis4.setRange(new Range(((TimeSeries)
								// me.getValue()).getMinY(), ((TimeSeries)
								// me.getValue()).getMaxY()));

								logger.debug(ts.getRecordingItem() + " is " + ((RecordingItem)ts.getRecordingItem()).isShow());
								// domainAxis.setLowerMargin(0.001);
								// domainAxis.setUpperMargin(0.0);
								//plot1.setRangeCrosshairLockedOnData(true);
								NumberAxis axis4=null;
								XYItemRenderer renderer=null;
								if (Preferences.getBooleanPreference("eventsAsDots")){
									
									axis4 = new LogarithmicAxis2(me.getKey().toString());
									axis4.setAutoRange(true);
										axis4.setDefaultAutoRange(new Range(-5000, 10* Math.exp(countEvent)+dataset.getRangeBounds(true).getUpperBound()));
									//	logger.info(countEvent+ " " + 10*Math.exp(countEvent)+ "  "+dataset.getRangeBounds(true).getUpperBound());
		//axis4.setAutoRangeMinimumSize(.001);
		//axis4.adjustedLog10(.001);
									//	axis4.setRange(-500000000, 1000);
								// axis4.setInverted(true);
								//		range.setVisible(((RecordingItem)ts.getRecordingItem()).getProcessingType().toString().equals("occurrences"));
										axis4.setAxisLineVisible(true);
									//	logger.info(((RecordingItem)ts.getRecordingItem()).getProcessingType());
										axis4.setAutoRangeIncludesZero(true);
									XYErrorRenderer rend = new XYErrorRenderer(); 
									rend.setCapLength(1);
									rend.setDrawYError(false);
									renderer = rend;
								}else {
									axis4 = new NumberAxis(me.getKey().toString());
									XYBarRenderer rend = new XYBarRenderer(0); // XYErrorRenderer
									 //rend.setMargin(100);
									axis4.setAutoRange(true);
									rend.setShadowVisible(false);
									rend.setDrawBarOutline(false);
									renderer = rend;
								}
								plot1.setRangeAxis(count, axis4);
		///////						plot1.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
								//plot1.setForegroundAlpha(1);
								plot1.setDataset(count, dataset);
								plot1.mapDatasetToRangeAxis(count, count);
					//			Stroke stroke = new BasicStroke(1f);
					//			rend.setBaseStroke(stroke);
								axis4.setLabelFont(new Font("Dialog", Font.PLAIN, 12));
								axis4.setVisible( ((RecordingItem)ts.getRecordingItem()).isShow());
									axis4.setLabelPaint(eventColorCache.getColor(me.getKey().toString()));
									axis4.setTickLabelPaint(eventColorCache.getColor(me.getKey().toString()));
								if (((RecordingItem)ts.getRecordingItem()).getProcessingType().toString().equals("occurrences")) {
									axis4.setTickLabelsVisible(false);
									axis4.setTickMarksVisible(false);
									axis4.setVerticalTickLabels(true);
									//belFont(new Font("Dialog", Font.BOLD, 6));
								}								
								renderer.setSeriesToolTipGenerator(0, tt1);
								// renderer.setItemLabelsVisible(true);
								renderer.setSeriesPaint(0, eventColorCache.getColor(me.getKey().toString()));
								renderer.setSeriesVisible(0, ((RecordingItem)ts.getRecordingItem()).isShow());
								plot1.setRenderer(count, renderer);
								int hits = 0;
								int matchs=0;
								
								if (((ExtendedTimeSeries) me.getValue()).getStat() != null) {
									hits = ((ExtendedTimeSeries) me.getValue()).getStat()[1];
								//	matchs= ((ExtendedTimeSeries) me.getValue()).getStat()[0];
								}
								JCheckBox jcb = new JCheckBox(new VisibleAction(cd,panel,checkboxPanel,axis4, me.getKey().toString() + "(" + hits + ")", 0));
								jcb.setSelected(((RecordingItem)ts.getRecordingItem()).isShow());
								jcb.setBackground(Color.white);
								jcb.setBorderPainted(true);
								jcb.setBorder(BorderFactory.createLineBorder(eventColorCache.getColor(me.getKey().toString()), 1, true));
								jcb.setFont(new Font("Sans-serif", oldSmallFont.getStyle(), oldSmallFont.getSize()));
								checkboxPanel.add(jcb);
								count++;
								countEvent++;
							}}
							
							Iterator eventMapIterator2 = eventMap.entrySet().iterator();
							while (eventMapIterator2.hasNext()) {
								TimeSeriesCollection dataset = new TimeSeriesCollection();
								Map.Entry me = (Map.Entry) eventMapIterator2.next();
								ExtendedTimeSeries ts = (ExtendedTimeSeries) me.getValue();
								// if (dataset.getEndXValue(series, item))
								if (!((RecordingItem)ts.getRecordingItem()).getProcessingType().toString().equals("occurrences")){
								if (((ExtendedTimeSeries) me.getValue()).getTimeSeries().getMaxY() > 0)
									dataset.addSeries(((ExtendedTimeSeries) me.getValue()).getTimeSeries());

								logger.debug("mineResultSet group: " + mr.getGroup() + ", key: " + me.getKey() + " nb records: "
										+ ((ExtendedTimeSeries) me.getValue()).getTimeSeries().getItemCount());
								logger.debug("mineResultSet hash content: " + mr.getEventTimeseriesMap());
								logger.debug("(((TimeSeries) me.getValue()).getMaxY(): " + (((ExtendedTimeSeries) me.getValue()).getTimeSeries().getMaxY()));
								logger.debug("(((TimeSeries) me.getValue()).getMinY(): " + (((ExtendedTimeSeries) me.getValue()).getTimeSeries().getMinY()));

							//	LogarithmicAxis axis4 = new LogarithmicAxis(me.toString());
								NumberAxis axis4 = new NumberAxis(me.getKey().toString());
								axis4.setAutoRange(true);

								// axis4.setInverted(true);
						//		range.setVisible(((RecordingItem)ts.getRecordingItem()).getProcessingType().toString().equals("occurrences"));
								axis4.setAxisLineVisible(!((RecordingItem)ts.getRecordingItem()).getProcessingType().toString().equals("occurrences"));
						//		logger.info(((RecordingItem)ts.getRecordingItem()).getProcessingType());
								axis4.setAutoRangeIncludesZero(true);
								// axis4.setRange(new Range(((TimeSeries)
								// axis4.setRange(new Range(((TimeSeries)
								// me.getValue()).getMinY(), ((TimeSeries)
								// me.getValue()).getMaxY()));
								axis4.setLabelFont(new Font("Dialog", Font.PLAIN, 12));
								axis4.setVisible( ((RecordingItem)ts.getRecordingItem()).isShow());
									axis4.setLabelPaint(eventColorCache.getColor(me.getKey().toString()));
									axis4.setTickLabelPaint(eventColorCache.getColor(me.getKey().toString()));
								if (((RecordingItem)ts.getRecordingItem()).getProcessingType().toString().equals("occurrences")) {
									axis4.setTickLabelsVisible(false);
									axis4.setTickMarksVisible(false);
									axis4.setVerticalTickLabels(true);
									//belFont(new Font("Dialog", Font.BOLD, 6));
								}
								logger.debug(ts.getRecordingItem() + " is " + ((RecordingItem)ts.getRecordingItem()).isShow());
								// domainAxis.setLowerMargin(0.001);
								// domainAxis.setUpperMargin(0.0);
								//plot1.setRangeCrosshairLockedOnData(true);
								plot1.setRangeAxis(count, axis4);
		///////						plot1.setRangeAxisLocation(AxisLocation.TOP_OR_LEFT);
							//	plot1.setForegroundAlpha(0.5f);
								plot1.setDataset(count, dataset);
								plot1.mapDatasetToRangeAxis(count, count);
								XYBarRenderer rend = new XYBarRenderer(); // XYErrorRenderer
								rend.setShadowVisible(false);
								rend.setDrawBarOutline(false);
								Stroke stroke = new BasicStroke(2);
								rend.setBaseStroke(stroke);
								final XYItemRenderer renderer = rend;
								renderer.setSeriesToolTipGenerator(0, tt1);
								// renderer.setItemLabelsVisible(true);
								renderer.setSeriesPaint(0, eventColorCache.getColor(me.getKey().toString()));
								renderer.setSeriesVisible(0, ((RecordingItem)ts.getRecordingItem()).isShow());
								plot1.setRenderer(count, renderer);
								int hits = 0;
								int matchs=0;
								
								if (((ExtendedTimeSeries) me.getValue()).getStat() != null) {
									hits = ((ExtendedTimeSeries) me.getValue()).getStat()[1];
								//	matchs= ((ExtendedTimeSeries) me.getValue()).getStat()[0];
								}
								JCheckBox jcb = new JCheckBox(new VisibleAction(cd,panel,checkboxPanel,axis4, me.getKey().toString() + "(" + hits + ")", 0));
								jcb.setSelected(((RecordingItem)ts.getRecordingItem()).isShow());
								jcb.setBackground(Color.white);
								jcb.setBorderPainted(true);
								jcb.setBorder(BorderFactory.createLineBorder(eventColorCache.getColor(me.getKey().toString()), 1, true));
								jcb.setFont(new Font("Sans-serif", oldSmallFont.getStyle(), oldSmallFont.getSize()));
								checkboxPanel.add(jcb);
								count++;
								countEvent++;
							}}
							
							
							while (statMapIterator.hasNext()) {

								TimeSeriesCollection dataset = new TimeSeriesCollection();
								String me = (String) statMapIterator.next();
								
								ExtendedTimeSeries ts = (ExtendedTimeSeries) statMap.get(me);
						//		if (ts.getTimeSeries().getMaxY() > 0)
									dataset.addSeries(ts.getTimeSeries());
								logger.debug("mineResultSet group: " + mr.getGroup() + ", key: " + me + " nb records: "
										+ ts.getTimeSeries().getItemCount());
								logger.debug("(((TimeSeries) me.getValue()).getMaxY(): " + (ts.getTimeSeries().getMaxY()));
								logger.debug("(((TimeSeries) me.getValue()).getMinY(): " + (ts.getTimeSeries().getMinY()));
								 
							//	LogarithmicAxis axis4 = new LogarithmicAxis(me.toString());
								NumberAxis axis4 = new NumberAxis(me.toString());
								axis4.setAutoRange(true);
								axis4.setAxisLineVisible(true);
								axis4.setAutoRangeIncludesZero(false);
								axis4.setRange(new Range(ts.getTimeSeries().getMinY(), ts
										.getTimeSeries().getMaxY()));
								axis4.setLabelPaint(statColorCache.getColor(me.toString()));
								axis4.setTickLabelPaint(statColorCache.getColor(me.toString()));
								plot1.setRangeAxis(count, axis4);
								axis4.setVisible(((RecordingItem)ts.getRecordingItem()).isShow());
								axis4.setLabelFont(new Font("Dialog", Font.PLAIN, 12));
								plot1.setForegroundAlpha(0.42f);
								if (ts.getTimeSeries().getMaxY()!=ts.getTimeSeries().getMinY()){
								plot1.setDataset(count, dataset);
								}
								plot1.mapDatasetToRangeAxis(count, count);
								final XYAreaRenderer renderer = new XYAreaRenderer(); // XYAreaRenderer2
																						// also
																						// nice
								renderer.setSeriesPaint(0, statColorCache.getColor(me.toString()));
								logger.debug(((RecordingItem)ts.getRecordingItem()).getName());
								renderer.setSeriesVisible(0, ((RecordingItem)ts.getRecordingItem()).isShow()); //!cd.disabledSeries.contains(me.toString()
								renderer.setSeriesToolTipGenerator(0, tt1);
								plot1.setRenderer(count, renderer);
								int hits = 0; // ts.getStat()[1]
								int matchs=0;
								if (((ExtendedTimeSeries) statMap.get(me)).getStat() != null) {
									hits = ts.getStat()[1];
								//	matchs= ((ExtendedTimeSeries) statMap.get(me)).getStat()[0];
								}
								JCheckBox jcb = new JCheckBox(new VisibleAction(cd,panel,checkboxPanel,axis4, me.toString() + "(" + hits + ")", 0));
								jcb.setSelected(((RecordingItem)ts.getRecordingItem()).isShow());
								jcb.setBackground(Color.white);
								jcb.setBorderPainted(true);
								jcb.setBorder(BorderFactory.createLineBorder(statColorCache.getColor(me.toString()), 1, true));
								jcb.setFont(new Font("Sans-serif", oldSmallFont.getStyle(), oldSmallFont.getSize()));
								logger.debug(me.toString()+", "+((RecordingItem)ts.getRecordingItem()).isShow());
					//			if (MainFrame.cd.disabledSeries.contains(me.toString())){
					//				jcb.setSelected(false);
					//			}
								checkboxPanel.add(jcb);
								count++;
								countStat++;
							}
		//					XYPlot plot1 = chart.getXYPlot();				
		//					final ValueAxis domainAxis = domainAxis1;
		//					final ValueAxis domainAxisa = domainAxis2;
		//					plot1.setDomainCrosshairVisible(true);
		//					plot1.setRangeCrosshairVisible(true);
		//					plot1.setDomainAxis(0,domainAxis);
		//					plot1.setDomainAxis(1,domainAxisa);
							


							final JPanel pan = new JPanel();
							
							pan.setLayout(new BorderLayout());
							pan.setMaximumSize(new Dimension(20000,Integer.parseInt((String)Preferences.getPreference("chartSize"))));
							pan.setPreferredSize(new Dimension(600, Integer.parseInt((String)Preferences.getPreference("chartSize"))));
							// pan.setPreferredSize(panelSize);
							panel.add(pan);
							final ChartPanel cpanel = new ChartPanel(chart);
							cpanel.setMinimumDrawWidth(0);
							cpanel.setMinimumDrawHeight(0);
							cpanel.setMaximumDrawWidth(1920);
							cpanel.setMaximumDrawHeight(Integer.parseInt((String)Preferences.getPreference("chartSize")));
							// cpanel.setInitialDelay(0);
							cpanel.setDismissDelay(9999999);
							cpanel.setInitialDelay(50);
							cpanel.setReshowDelay(200);
							cpanel.setPreferredSize(new Dimension(600, Integer.parseInt((String)Preferences.getPreference("chartSize"))));
							// cpanel.restoreAutoBounds(); fix the tooltip
							// missing problem but then relative display is
							// broken
							
							JPanel panTitle = new JPanel();
							JButton removeButton = new JButton("x");
							removeButton.setMargin(new Insets(0,0,0,0));
							removeButton.setPreferredSize(new Dimension(17, 15));
							panTitle.setLayout(new BorderLayout(0, 0));
							panTitle.setPreferredSize(new Dimension(600, 20));
							JPanel chartTitlePanel1 = new JPanel();
							chartTitlePanel1.setBackground(Color.WHITE);
							panTitle.add(chartTitlePanel1, BorderLayout.WEST);
							chartTitlePanel1.setLayout(new GridLayout(0, 1, 0, 0));
							FastDateFormat sdf = FastDateFormat.getInstance("dd-MMM-yyyy HH:mm:ss");
							JLabel chartTitleStartDateLbl = new JLabel("    "+sdf.format(mr.getStartDate()));
							chartTitleStartDateLbl.setFont(new Font("Verdana", Font.PLAIN, 10));
						    chartTitleStartDateLbl.setVerticalAlignment(SwingConstants.BOTTOM);
							chartTitlePanel1.add(chartTitleStartDateLbl);
							JPanel chartTitlePanel2 = new JPanel();
							FlowLayout flowLayout = (FlowLayout) chartTitlePanel2.getLayout();
							flowLayout.setAlignment(FlowLayout.LEFT);
							chartTitlePanel2.setBackground(Color.WHITE);
							panTitle.add(chartTitlePanel2, BorderLayout.CENTER);
							JLabel chartTitleSourceLbl = new JLabel("         "+mr.getSourceID() + " " + mr.getGroup());
							chartTitleSourceLbl.setFont(new Font("Verdana", Font.BOLD, 12));
							chartTitlePanel2.add(chartTitleSourceLbl);	
							panTitle.add(removeButton, BorderLayout.EAST);
							removeButton.addActionListener(new ActionListener() {
								public void actionPerformed(ActionEvent e) {
									pan.setVisible(false);
								}
							});

							// checkboxPanel.setPreferredSize(new Dimension(600,
							// 0));
							cpanel.addChartMouseListener(new ChartMouseListener() {

								public void chartMouseClicked(ChartMouseEvent chartmouseevent) {
									// chartmouseevent.getEntity().

									ChartEntity entity = chartmouseevent.getEntity();
									if (entity instanceof XYItemEntity) {
										XYItemEntity item = ((XYItemEntity) entity);
										if (item.getDataset() instanceof TimeSeriesCollection) {
											
											TimeSeriesCollection data = (TimeSeriesCollection) item.getDataset();
											TimeSeries series = data.getSeries(item.getSeriesIndex());
											TimeSeriesDataItem dataitem = series.getDataItem(item.getItem());

											// logger.info(" Serie: "+series.getKey().toString()
											// +
											// " Period : "+dataitem.getPeriod().toString());
											// mr.getFileForDate(new Date
											// (x.longValue())
											;
											int x = chartmouseevent.getTrigger().getX();
											// logger.info(mr.getFileForDate(dataitem.getPeriod().getEnd()));
											int y = chartmouseevent.getTrigger().getY();
											String myString = "";
											if (dataitem.getPeriod() != null) {
												logger.info(dataitem.getPeriod().getEnd());
//												myString = mr.getFileForDate(dataitem.getPeriod().getEnd()).toString();
												String lineString=""+mr.getFileLineForDate(dataitem.getPeriod().getEnd(),item.getDataset().getSeriesKey(item.getSeriesIndex()).toString()).getLineNumber();
												String fileString=cd.sourceFileArrayListMap.get(pairs.getKey()).get(mr.getFileLineForDate(dataitem.getPeriod().getEnd(),item.getDataset().getSeriesKey(item.getSeriesIndex()).toString()).getFileId()).getFile().getAbsolutePath();
												String command=Preferences.getPreference("editorCommand");
												command=command.replace("$line", lineString);
												command=command.replace("$file", fileString);
												logger.info(command);
												Runtime rt = Runtime.getRuntime();
												try {
													rt.exec(command);
												} catch (IOException e1) {
													// TODO Auto-generated catch block
													e1.printStackTrace();
												}
												StringSelection stringSelection = new StringSelection(fileString);
												Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard();
												clpbrd.setContents(stringSelection, null);
										//		cpanel.getGraphics().drawString("file name copied", x - 5, y - 5);
												try {
													Thread.sleep(500);
												} catch (InterruptedException e) {
													// TODO Auto-generated catch
													// block
													e.printStackTrace();
												}
											}

											// logger.info(mr.getFileForDate(dataitem.getPeriod().getStart()));
										}
									}
								}

								public void chartMouseMoved(ChartMouseEvent e) {
								}

							});
							JPanel graphAndChecks = new JPanel(new BorderLayout(0,0));
							graphAndChecks.add(cpanel, BorderLayout.CENTER);
							graphAndChecks.add(checkboxPanel, BorderLayout.SOUTH);
							pan.add(panTitle, BorderLayout.NORTH);
							pan.add(graphAndChecks, BorderLayout.CENTER);
							pan.add(new JSeparator(SwingConstants.HORIZONTAL),BorderLayout.SOUTH);	

						}
					}
				} else {
					logger.debug("mr dates null: " + mr.getGroup() + mr.getSourceID() + mr.getLogFiles());
				}
			}
		}}
		// Map=miner.mine(sourceFiles,repo);
		JPanel panEnd = new JPanel();
		
		panEnd.setLayout(new BorderLayout());
		panEnd.setPreferredSize(new Dimension(600, 0));
		// pan.setPreferredSize(panelSize);
		panel.add(panEnd);
		estimatedTime = System.currentTimeMillis() - startTime;
		revalidate();
		logger.info("display time: " + estimatedTime);
	   	//panel.transferFocus();
	  //	panel.requestFocus();
	}

	private static class VisibleAction extends AbstractAction {

		NumberAxis localAxis;
		private int i;
		JPanel jpanel;
		String name;
		JPanel checkBoxPanel;
		ChartData cd;
		
		public VisibleAction(ChartData cd1,JPanel panel,JPanel checkBoxPanel,NumberAxis axis, String name, int i) {
			super(name);
			this.localAxis=axis;
			this.i = i;
			this.name=name.substring(0, ((name).indexOf("(")));
			this.checkBoxPanel=checkBoxPanel;
			jpanel=panel;
			cd=cd1;
		}

		@Override
		public void actionPerformed(ActionEvent e) {
		/*	if (!mainFrame1.cd.disabledSeries.contains(name)){
				if (logger.isDebugEnabled()){
					logger.debug("add "+ name);
				}
				mainFrame1.cd.addDisabledSeries(name);
			}else {
				if (logger.isDebugEnabled()){
					logger.debug("remove "+ name);
				}
				mainFrame1.cd.removeDisabledSeries(name);
			}
			if (logger.isDebugEnabled()){
				logger.debug("cd.disabledSeries: "+ mainFrame1.cd.disabledSeries );
			}*/
		//	renderer.setSeriesVisible(i, !renderer.getSeriesVisible(i));
		//	localAxis.setVisible(!localAxis.isVisible());
			Component[] comp=jpanel.getComponents();
			int i=0;
			while (i<comp.length-1){
				if (comp[i].getClass().equals(JPanel.class)){
				//logger.info(i+" / "+comp.length+ " is Jpanel " + ((JPanel)comp[i]).getComponentCount() + " and " + ((JPanel)comp[i]).getComponent(1));
					if (((JPanel)comp[i]).getComponent(1).getClass().equals(JPanel.class)){
				//		logger.info( ((JPanel) ((JPanel)comp[i]).getComponent(1)).getComponent(0).getClass());
					if (((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(0).getClass().equals(ChartPanel.class)){
					//	logger.info("is ChartPanel");
					int nbAxis=((ChartPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(0)).getChart().getXYPlot().getRangeAxisCount();
					if (logger.isDebugEnabled()){
						logger.debug(nbAxis);
						logger.debug(((ChartPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(0)).getChart().getTitle().getText());
					}					
					int i2=0;
					while (i2<nbAxis){
						if (((ChartPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(0)).getChart().getXYPlot().getRangeAxis(i2).getLabel()!=null && ((ChartPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(0)).getChart().getXYPlot().getRangeAxis(i2).getLabel().toString().equals(localAxis.getLabel().toString())){
							((ChartPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(0)).getChart().getXYPlot().getRangeAxis(i2).setVisible(!((ChartPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(0)).getChart().getXYPlot().getRangeAxis(i2).isVisible());;
							((ChartPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(0)).getChart().getXYPlot().getRenderer(i2).setSeriesVisible(0, !((ChartPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(0)).getChart().getXYPlot().getRenderer(i2).isSeriesVisible(0));	
						}
						i2++;
						}
					Component[] comp2=((JPanel)((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(1)).getComponents();
					int i3=0;
					while (i3<comp2.length){
						if ( ((JCheckBox)comp2[i3]).getText().substring(0, ((((JCheckBox)comp2[i3]).getText()).indexOf("("))).equals(name)&& !((JPanel)((JPanel)comp[i]).getComponent(1)).getComponent(1).equals(checkBoxPanel)){
							((JCheckBox)comp2[i3]).setSelected(!((JCheckBox)comp2[i3]).isSelected());
						}
						i3++;
						}
				}}
				i++;
			}
		}

	}
}
} final public class FileChooserDialog {

	/*
	 * -------------------------------------------------------------------------
	 * Public attributes
	 * -------------------------------------------------------------------------
	 */

	/*
	 * -------------------------------------------------------------------------
	 * Private attributes
	 * -------------------------------------------------------------------------
	 */
	/**
	 * The previous location were the last file has been opened.
	 */
	static private File previousOpenLocation = new File(".");

	/**
	 * The JFileChooser used to display the open fle dialog box.
	 */
	private JFileChooser dialog = new JFileChooser();

	/**
	 * The JFileChooser result.
	 */
	private int result = JFileChooser.CANCEL_OPTION;

	/*--------------------------------------------------------------------------
	 * Constructor(s)
	 *--------------------------------------------------------------------------*/
	/**
	 * Construct a File Chooser and display the file selection dialog
	 */
	public FileChooserDialog() {

		dialog.setCurrentDirectory(previousOpenLocation);
		dialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		dialog.setMultiSelectionEnabled(true);

		// Multi Selection mode.
		// NOTE This mode is not yet implemented in the java 1.2 L&Fs.
		// _dialog.setMultiSelectionEnabled(true);

		result = dialog.showOpenDialog(null);

		if (result == JFileChooser.APPROVE_OPTION) {

			// Memorisation des valeurs pour les afficher lors du prochain
			// affichage d'un dialogue d'ouverture de fichier.
			previousOpenLocation = dialog.getCurrentDirectory();
		}
	}

	/*--------------------------------------------------------------------------
	 * Constructor(s)
	 *--------------------------------------------------------------------------*/
	/**
	 * Construct a File Chooser and display the file selection dialog
	 */
	public FileChooserDialog(File previousLocation) {

		if (previousLocation.exists() && previousLocation.isDirectory()) {
			dialog.setCurrentDirectory(previousLocation);
		} else {
			dialog.setCurrentDirectory(previousOpenLocation);
		}
		dialog.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		dialog.setMultiSelectionEnabled(true);

		// Multi Selection mode.
		// NOTE This mode is not yet implemented in the java 1.2 L&Fs.
		// _dialog.setMultiSelectionEnabled(true);

		result = dialog.showOpenDialog(null);

		if (result == JFileChooser.APPROVE_OPTION) {

			// Memorisation des valeurs pour les afficher lors du prochain
			// affichage d'un dialogue d'ouverture de fichier.
			previousOpenLocation = dialog.getCurrentDirectory();
		}
	}

	/*
	 * -------------------------------------------------------------------------
	 * Public methods
	 * -------------------------------------------------------------------------
	 */
	/**
	 * Returns the selected file in mono-file selection mode
	 */
	public File getSelectedFile() {
		return dialog.getSelectedFile();
	}

	/**
	 * Returns a list of selected files in the multi-selection mode.
	 * <p>
	 * <b>Warning:</b> This mode is not yet implemented in the java 1.2 L&Fs.
	 */
	public File[] getSelectedFiles() {
		File[] returnValue;

		if (dialog.isMultiSelectionEnabled()) {
			returnValue = dialog.getSelectedFiles();
		} else {
			returnValue = null;
		}
		return returnValue;
	}

	/**
	 * Returns true is the user choose the approve button of the file chooser
	 * dialog box.
	 */
	public boolean isValidate() {
		return (result == JFileChooser.APPROVE_OPTION);
	}

	/**
	 * Returns true if multiple files can be selected.
	 * <p>
	 * <b>Warning:</b> This functionnality is not yet implemented in the java
	 * 1.2 L&Fs.
	 */
	public boolean isMultiSelectionEnabled() {
		return dialog.isMultiSelectionEnabled();
	}

	/*
	 * -------------------------------------------------------------------------
	 * Private methods
	 * -------------------------------------------------------------------------
	 */

} final public class FileSaverDialog {
	private static Logger logger = Logger.getLogger(FileSaverDialog.class.getName());
	/**
	 * The previous location were the last file has been opened.
	 */
	static private File previousOpenLocation = new File(".");

	/**
	 * The JFileChooser used to display the open fle dialog box.
	 */
	private JFileChooser dialog = new JFileChooser();

	/**
	 * The JFileChooser result.
	 */
	private int result = JFileChooser.CANCEL_OPTION;

	/*--------------------------------------------------------------------------
	 * Constructor(s)
	 *--------------------------------------------------------------------------*/
	/**
	 * Construct a File Chooser and display the file selection dialog
	 */
	public FileSaverDialog(Repository repo) {

		if (Preferences.getPreference("lastPath")!=null) {
			File temp= new File(Preferences.getPreference("lastPath"));
			if (temp.exists())
			previousOpenLocation=new File (Preferences.getPreference("lastPath"));
		}
		dialog.setCurrentDirectory(previousOpenLocation);
		dialog.setFileSelectionMode(JFileChooser.FILES_ONLY);
		dialog.setMultiSelectionEnabled(false);

		// Multi Selection mode.
		// NOTE This mode is not yet implemented in the java 1.2 L&Fs.
		// _dialog.setMultiSelectionEnabled(true);

		result = dialog.showOpenDialog(null);

		if (result == JFileChooser.APPROVE_OPTION) {

			// Memorisation des valeurs pour les afficher lors du prochain
			// affichage d'un dialogue d'ouverture de fichier.
			previousOpenLocation = dialog.getCurrentDirectory();
			Preferences.setPreference("lastPath", previousOpenLocation.getAbsolutePath());
			Preferences.persist();
		}
	}

	/*
	 * -------------------------------------------------------------------------
	 * Public methods
	 * -------------------------------------------------------------------------
	 */
	/**
	 * Returns the selected file in mono-file selection mode
	 */
	public File getSelectedFile() {
		return dialog.getSelectedFile();
	}

	/**
	 * Returns a list of selected files in the multi-selection mode.
	 * <p>
	 * <b>Warning:</b> This mode is not yet implemented in the java 1.2 L&Fs.
	 */
	public File[] getSelectedFiles() {
		File[] returnValue;

		if (dialog.isMultiSelectionEnabled()) {
			returnValue = dialog.getSelectedFiles();
		} else {
			returnValue = null;
		}
		return returnValue;
	}

	/**
	 * Returns true is the user choose the approve button of the file chooser
	 * dialog box.
	 */
	public boolean isValidate() {
		return (result == JFileChooser.APPROVE_OPTION);
	}

	/**
	 * Returns true if multiple files can be selected.
	 * <p>
	 * <b>Warning:</b> This functionnality is not yet implemented in the java
	 * 1.2 L&Fs.
	 */
	public boolean isMultiSelectionEnabled() {
		return dialog.isMultiSelectionEnabled();
	}

	/*
	 * -------------------------------------------------------------------------
	 * Private methods
	 * -------------------------------------------------------------------------
	 */

} public class DateEditor extends JPanel {
	private static Logger logger = Logger.getLogger(DataMiner.class.getName());
	private JTable table;
	JPanel jPanelDetail;
	boolean DEBUG = false;
	static Matcher m;
	static ArrayList<DateFormat> dateFormats = null;
	private String[] header = { "name", "pattern", "FastDateFormat" };
	private ArrayList<Object[]> data = new ArrayList<Object[]>();
	private Repository repository = null;
	private StatRecordingEditor recEditor = null;
	public MyTableModel2 model;
	private JTextField textFieldName;
	private JTextField textFieldPattern;
	private JLabel labelPattern;
	private GridBagConstraints gbc_jPanelDetail;
	private JTextField textField;

	/**
	 * Create the panel.
	 */
	public DateEditor(Repository rep) {
		repository = rep;
		model = new MyTableModel2(data, header);

		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[] { 15, 550, 15 };
		gridBagLayout.rowHeights = new int[] { 152, 300 };
		gridBagLayout.columnWeights = new double[] { 0.0, 1.0, 0.0 };
		gridBagLayout.rowWeights = new double[] { 0.0, 1.0 };
		setLayout(gridBagLayout);

		JPanel panel_1 = new JPanel();
		GridBagConstraints gbc_panel_1 = new GridBagConstraints();
		gbc_panel_1.fill = GridBagConstraints.BOTH;
		gbc_panel_1.insets = new Insets(5, 0, 5, 5);
		gbc_panel_1.gridx = 1;
		gbc_panel_1.gridy = 0;
		add(panel_1, gbc_panel_1);
		panel_1.setLayout(new BorderLayout(0, 0));
		panel_1.setMinimumSize(new Dimension(0, 200));
		panel_1.setPreferredSize(new Dimension(0, 200));
		table = new JTable(model);
		table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		table.setBorder(UIManager.getBorder("TextPane.border"));
		table.setPreferredScrollableViewportSize(new Dimension(0, 0));
		table.setFillsViewportHeight(true);

		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			public void valueChanged(ListSelectionEvent e) {
				// ((table.getSelectedRow()!=-1)?table.convertRowIndexToModel(table.getSelectedRow()):-1)
				// persist repository
				// display selected row

				if (((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1) >= 0) {
					/*
					 * recEditor = new RecordingEditor(repository
					 * .getRecordings().get(((table.getSelectedRow()!=-1)?table.
					 * convertRowIndexToModel(table.getSelectedRow()):-1)),
					 * repository); jPanelDetail.removeAll();
					 */
					// jPanelDetail.add(recEditor, gbc_jPanelDetail);
					DateFormat df = repository.getDateFormat(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1)).clone();
					if (df != null) {
						textFieldName.setText((String) df.getName());
						textFieldPattern.setText((String) df.getPattern());
						textField.setText((String) df.getDateFormat());
					}
					// jPanelDetail.revalidate();
					// jPanelDetail.repaint();
					// jPanelDetail.setVisible(true);
					// reloadTable(); those 2 ********
					// jPanelDetail.revalidate();
				}
			}
		});

		JScrollPane scrollPane = new JScrollPane(table);
		panel_1.add(scrollPane, BorderLayout.CENTER);
		// Set up column sizes.
		initColumnSizes(table);

		JPanel panel = new JPanel();
		FlowLayout flowLayout = (FlowLayout) panel.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);
		flowLayout.setVgap(2);
		flowLayout.setHgap(2);
		panel_1.add(panel, BorderLayout.SOUTH);

		JButton btnNew = new JButton("New");
		panel.add(btnNew);
		btnNew.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				DateFormat df = new DateFormat("name", "\\w{3}\\s[0-9]{1}/[0-9]{2}/[0-9]{2}\\s\\d\\d:\\d\\d:\\d\\d", "EEE. MM/dd/yy HH:mm:ss");
				repository.addDateFormat(df);
				data.add(new Object[] { df.getName(), df.getPattern(), df.getDateFormat() });
				table.repaint();
			}
		});

		JButton btnDuplicate = new JButton("Duplicate");
		btnDuplicate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1) >= 0) {
					DateFormat df = repository.getDateFormat(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1)).clone();
					repository.addDateFormat(df);
					reloadTable();
					data.add(new Object[] { df.getName(), df.getPattern(), df.getDateFormat() });
					table.repaint();
				}
			}
		});
		panel.add(btnDuplicate);

		JButton btnDelete = new JButton("Delete");
		btnDelete.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
				if (selectedRow >= 0) {
					repository.deleteDateFormat(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
					data.remove(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
					reloadTable();
					table.setRowSelectionInterval(selectedRow, selectedRow);
					table.repaint();
				}
			}
		});
		panel.add(btnDelete);

		jPanelDetail = new JPanel();
		gbc_jPanelDetail = new GridBagConstraints();
		gbc_jPanelDetail.anchor = GridBagConstraints.NORTH;
		gbc_jPanelDetail.fill = GridBagConstraints.HORIZONTAL;
		gbc_jPanelDetail.gridx = 1;
		gbc_jPanelDetail.gridy = 1;
		add(jPanelDetail, gbc_jPanelDetail);
		GridBagLayout gbl_jPanelDetail = new GridBagLayout();
		gbl_jPanelDetail.columnWidths = new int[] { 169 };
		gbl_jPanelDetail.rowHeights = new int[] { 0, 0, 0, 0, 150, 0 };
		gbl_jPanelDetail.columnWeights = new double[] { 1.0, 0.0 };
		gbl_jPanelDetail.rowWeights = new double[] { 0.0, 0.0, 0.0, 1.0, 1.0, 0.0 };
		jPanelDetail.setLayout(gbl_jPanelDetail);

		JPanel panel_2 = new JPanel();
		panel_2.setBorder(null);
		GridBagConstraints gbc_panel_2 = new GridBagConstraints();
		gbc_panel_2.gridwidth = 2;
		gbc_panel_2.anchor = GridBagConstraints.NORTHWEST;
		gbc_panel_2.insets = new Insets(0, 0, 5, 0);
		gbc_panel_2.gridx = 0;
		gbc_panel_2.gridy = 0;
		jPanelDetail.add(panel_2, gbc_panel_2);
		panel_2.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));

		JLabel label = new JLabel("Name");
		panel_2.add(label);

		textFieldName = new JTextField();
		textFieldName.setColumns(20);
		panel_2.add(textFieldName);

		JPanel panel_3 = new JPanel();
		FlowLayout flowLayout_1 = (FlowLayout) panel_3.getLayout();
		flowLayout_1.setAlignment(FlowLayout.LEFT);
		panel_3.setBorder(null);
		GridBagConstraints gbc_panel_3 = new GridBagConstraints();
		gbc_panel_3.insets = new Insets(0, 0, 5, 0);
		gbc_panel_3.gridwidth = 2;
		gbc_panel_3.anchor = GridBagConstraints.NORTHWEST;
		gbc_panel_3.gridx = 0;
		gbc_panel_3.gridy = 1;
		jPanelDetail.add(panel_3, gbc_panel_3);

		labelPattern = new JLabel("Pattern");
		panel_3.add(labelPattern);

		textFieldPattern = new JTextField();
		textFieldPattern.setColumns(40);
		panel_3.add(textFieldPattern);

		JButton btnSave = new JButton("Save");
		btnSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				DateFormat df1 = repository.getDateFormat(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
				df1.update(textFieldName.getText(), textFieldPattern.getText(), textField.getText());
				reloadTable();
			}
		});

		JPanel panel_4 = new JPanel();
		FlowLayout flowLayout_2 = (FlowLayout) panel_4.getLayout();
		flowLayout_2.setAlignment(FlowLayout.LEFT);
		GridBagConstraints gbc_panel_4 = new GridBagConstraints();
		gbc_panel_4.anchor = GridBagConstraints.WEST;
		gbc_panel_4.insets = new Insets(0, 0, 5, 5);
		gbc_panel_4.gridx = 0;
		gbc_panel_4.gridy = 2;
		jPanelDetail.add(panel_4, gbc_panel_4);

		JLabel lblFastDateFormat = new JLabel("FastDateFormat");
		panel_4.add(lblFastDateFormat);

		textField = new JTextField();
		panel_4.add(textField);
		textField.setColumns(30);

		JPanel panel_5 = new JPanel();
		FlowLayout flowLayout_3 = (FlowLayout) panel_5.getLayout();
		flowLayout_3.setAlignment(FlowLayout.LEFT);
		GridBagConstraints gbc_panel_5 = new GridBagConstraints();
		gbc_panel_5.insets = new Insets(0, 0, 5, 5);
		gbc_panel_5.fill = GridBagConstraints.BOTH;
		gbc_panel_5.gridx = 0;
		gbc_panel_5.gridy = 3;
		jPanelDetail.add(panel_5, gbc_panel_5);

		JLabel lblSampleLabel = new JLabel("Sample");
		panel_5.add(lblSampleLabel);

		JPanel panel_6 = new JPanel();
		panel_6.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		GridBagConstraints gbc_panel_6 = new GridBagConstraints();
		gbc_panel_6.ipady = 1;
		gbc_panel_6.ipadx = 1;
		gbc_panel_6.insets = new Insets(0, 0, 5, 5);
		gbc_panel_6.fill = GridBagConstraints.BOTH;
		gbc_panel_6.gridx = 0;
		gbc_panel_6.gridy = 4;
		jPanelDetail.add(panel_6, gbc_panel_6);
		panel_6.setLayout(new BorderLayout(0, 0));

		JTextPane textPane = new JTextPane();
		textPane.setBackground(UIManager.getColor("windowBorder"));
		panel_6.add(textPane);
		GridBagConstraints gbc_btnSave = new GridBagConstraints();
		gbc_btnSave.insets = new Insets(0, 0, 0, 5);
		gbc_btnSave.gridx = 0;
		gbc_btnSave.gridy = 5;
		jPanelDetail.add(btnSave, gbc_btnSave);
		reloadTable();
	}

	public void reloadTable() {
		int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
		dateFormats = repository.getDates();
		// Collections.sort(records);
		if (dateFormats != null) {
			Iterator it = dateFormats.iterator();
			int count = 0;
			data.clear();
			// this.repaint();
			while (it.hasNext()) {
				DateFormat record = (DateFormat) it.next();
				data.add(new Object[] { record.getName(), record.getPattern(), record.getDateFormat() });
				logger.info(count + record.getName() + record.getPattern() + record.getDateFormat());
			}
			model.fireTableDataChanged();
			// this.repaint();
			// table.repaint();
			// table.revalidate(); ******************** removed to workaround
			// NPE
			if (selectedRow >= 0) {
				if (selectedRow <= table.getRowCount()) {
					table.setRowSelectionInterval(selectedRow, selectedRow);
				} else
					table.setRowSelectionInterval(selectedRow - 1, selectedRow - 1);
			} else if (table.getRowCount() > 0) {
				table.setRowSelectionInterval(0, 0);
			}
			this.revalidate();
		}
	}

	private void initColumnSizes(JTable theTable) {
		MyTableModel2 model = (MyTableModel2) theTable.getModel();
		TableColumn column = null;
		Component comp = null;
		int headerWidth = 0;
		int cellWidth = 0;
		// Object[] longValues = model.longValues;
		TableCellRenderer headerRenderer = theTable.getTableHeader().getDefaultRenderer();

		for (int i = 0; i < 3; i++) {
			column = theTable.getColumnModel().getColumn(i);

			comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
			headerWidth = comp.getPreferredSize().width;

			/*
			 * comp = table.getDefaultRenderer(model.getColumnClass(i)).
			 * getTableCellRendererComponent( table, longValues[i], false,
			 * false, 0, i);
			 */
			cellWidth = comp.getPreferredSize().width;

			if (DEBUG) {
				logger.info("Initializing width of column " + i + ". " + "headerWidth = " + headerWidth + "; cellWidth = " + cellWidth);
			}

			column.setPreferredWidth(Math.max(headerWidth, cellWidth));
		}
	}

	class MyTableModel2 extends AbstractTableModel {
		private String[] header;
		private ArrayList<Object[]> data;

		public MyTableModel2(ArrayList<Object[]> data, String[] header) {
			this.header = header;
			this.data = data;
		}

		@Override
		public int getColumnCount() {
			if (header == null) {
				return 0;
			} else
				return header.length;
		}

		@Override
		public String getColumnName(int column) {
			return header[column];
		}

		@Override
		public int getRowCount() {
			return data.size();
		}

		public void addRow(Object[] obj) {
			data.add(obj);
		}

		public void updateRow(int rowId, Object[] obj) {
			data.set(rowId, obj);
		}

		@Override
		public Object getValueAt(int row, int column) {
			return data.get(row)[column];
		}

		@Override
		public void setValueAt(Object value, int row, int column) {
			data.get(row)[column] = value;
			fireTableCellUpdated(row, column);
		}

		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			// Note that the data/cell address is constant,
			// no matt&er where the cell appears onscreen.
			if (col < 0) {
				return false;
			} else {
				return true;
			}
		}

		/*
		 * Don't need to implement this method unless your table's data can
		 * change.
		 */
		/*
		 * public void setValueAt(Object value, int row, int col) { if (DEBUG) {
		 * logger.info("Setting value at " + row + "," + col + " to " + value +
		 * " (an instance of " + value.getClass() + ")"); }
		 * 
		 * data[row][col] = value; fireTableCellUpdated(row, col);
		 * 
		 * if (DEBUG) { logger.info("New value of data:"); printDebugData(); } }
		 * 
		 * private void printDebugData() { int numRows = getRowCount(); int
		 * numCols = getColumnCount();
		 * 
		 * for (int i=0; i < numRows; i++) { System.out.print("    row " + i +
		 * ":"); for (int j=0; j < numCols; j++) { System.out.print("  " +
		 * data[i][j]); } logger.info(); }
		 * logger.info("--------------------------"); }
		 */
	}

	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event-dispatching thread.
	 * 
	 * private static void createAndShowGUI() { // Create and set up the window.
	 * JFrame frame = new JFrame("RecordingEditorTable");
	 * frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	 * 
	 * // Create and set up the content pane. ReportPanel newContentPane = new
	 * ReportPanel(null, repository); newContentPane.setOpaque(true); //
	 * content panes must be opaque frame.setContentPane(newContentPane);
	 * 
	 * // Display the window. frame.pack(); frame.setVisible(true); }
	 */

	/*
	 * public ArrayList<RecordingItem> getRecordingItems() {
	 * ArrayList<RecordingItem> toReturn = new ArrayList<RecordingItem>(); for
	 * (int i = 0; i < data.size(); i++) { // model.getRowCount()
	 * toReturn.add(new RecordingItem((String) model.getValueAt(i, 0),(String)
	 * model.getValueAt(i, 1), (String) model.getValueAt(i, 2), (Boolean)
	 * model.getValueAt(i, 3)); } return toReturn; }
	 */

	/*
	 * public void Add() { data.add(new Object[] { " ", "", "long", "",
	 * Boolean.TRUE, "" }); table.repaint(); }
	 */

	public void Remove() {
		data.remove(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		repository.deleteRecording(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		table.repaint();
	}

	/*
	 * private ArrayList<DateFormat> findRecordItems(String theLine) {
	 * FastDateFormat FastDateFormat = new FastDateFormat(
	 * "EEE MM/dd/yy HH:mm:ss"); String[] rIString = theLine.split(", ");
	 * ArrayList<RecordingItem> rI = new ArrayList<RecordingItem>(); for (int i
	 * = 0; i < rIString.length; i++) { if (i == 0) { String[] splitted =
	 * rIString[i].split(": "); String date = splitted[0]; try {
	 * FastDateFormat.parse(date); } catch (ParseException e) { // TODO
	 * Auto-generated catch block e.printStackTrace(); } } else { if
	 * (rIString[i].contains("=")) { String[] splitted = rIString[i].split("=");
	 * String name = splitted[0]; String value = splitted[1]; // rI.add(new
	 * RecordingItem(name,value,true)); logger.info(name + " " + value); } } }
	 * return rI; }
	 */
}
 public class EventRecordingSelectorPanel extends JPanel {
	private static Logger logger = Logger.getLogger(EventRecordingSelectorPanel.class.getName());
	public static JTable table;
	JPanel jPanelDetail;
	EventRecordingSelectorPanel thiis = this;
	boolean DEBUG = false;
	static Matcher m;
	static ArrayList records = null;
	private String[] header = { "name", "regexp", "type", "active" };
	private Vector<Object[]> data = new Vector<Object[]>();
	private Repository repository = null;
	private JPanel recEditor = null;
	public logdruid.ui.mainpanel.EventRecordingSelectorPanel.MyTableModel model;
	private Source source;

	/**
	 * Create the panel.
	 */
	public EventRecordingSelectorPanel(final Repository rep, Source src) {
		repository = rep;
		source = src;
		records = rep.getRecordings(EventRecording.class,true);
		// Collections.sort(records);
		Iterator it = records.iterator();
		while (it.hasNext()) {
			Recording record = (Recording) it.next();
				data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), src.isActiveRecordingOnSource(record) });
			}
		
		model = new logdruid.ui.mainpanel.EventRecordingSelectorPanel.MyTableModel(data, header);
		logger.debug("source is " + ((source == null) ? "null" : src.getSourceName()));
		JPanel panel_1 = new JPanel();
		GridBagConstraints gbc_panel_1 = new GridBagConstraints();
		gbc_panel_1.fill = GridBagConstraints.BOTH;
		gbc_panel_1.insets = new Insets(5, 0, 5, 5);
		gbc_panel_1.gridx = 1;
		gbc_panel_1.gridy = 0;
		panel_1.setLayout(new BorderLayout(0, 0));

		table = new JTable(model);
		JScrollPane scrollPane = new JScrollPane(table);
		panel_1.add(scrollPane, BorderLayout.CENTER);

		table.setPreferredScrollableViewportSize(new Dimension(0, 150));
		table.setFillsViewportHeight(true);
		table.setAutoCreateRowSorter(true);

		// Set up column sizes.
		initColumnSizes(table);

		setLayout(new BorderLayout(0, 0));

		JSplitPane splitPane = new JSplitPane();
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		add(splitPane);
		jPanelDetail = new JPanel();
		splitPane.setBottomComponent(jPanelDetail);
		splitPane.setTopComponent(panel_1);

		GridBagConstraints gbc_jPanelDetail = new GridBagConstraints();
		gbc_jPanelDetail.insets = new Insets(0, 0, 0, 5);
		gbc_jPanelDetail.fill = GridBagConstraints.BOTH;
		gbc_jPanelDetail.gridx = 1;
		gbc_jPanelDetail.gridy = 3;
		jPanelDetail.setLayout(new BorderLayout(0, 0));
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			public void valueChanged(ListSelectionEvent e) {
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
				logger.debug("ListSelectionListener - selectedRow: " + selectedRow);
				if (selectedRow >= 0) {
					if (jPanelDetail != null) {
						logger.debug("ListSelectionListener - valueChanged");
						jPanelDetail.removeAll();
						recEditor = getEditor(repository.getRecording(EventRecording.class, selectedRow,true));
						if (recEditor != null) {
							jPanelDetail.add(recEditor, BorderLayout.CENTER);
						}
						jPanelDetail.revalidate();
					}
				}
			}
		});
		if (repository.getRecordings(EventRecording.class,true).size() > 0) {
			recEditor = getEditor(repository.getRecording(EventRecording.class, 0,true));
			jPanelDetail.add(recEditor, BorderLayout.CENTER);
			table.setRowSelectionInterval(0, 0);
		}
		if (model.getRowCount()>0){
			table.getRowSorter().toggleSortOrder(0);
			table.setRowSelectionInterval(0, 0);
		}
	}

	private JPanel getEditor(Recording rec) {
			return new EventRecordingEditor(this,repository, rec.getExampleLine(), rec.getRegexp(), ((EventRecording) rec));
	}

	private void initColumnSizes(JTable theTable) {
		TableColumn column = null;
		Component comp = null;
		int headerWidth = 0;
		int cellWidth = 0;
		TableCellRenderer headerRenderer = theTable.getTableHeader().getDefaultRenderer();

		for (int i = 0; i < 4; i++) {
			column = theTable.getColumnModel().getColumn(i);
			comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
			headerWidth = comp.getPreferredSize().width;
			cellWidth = comp.getPreferredSize().width;
			column.setPreferredWidth(Math.max(headerWidth, cellWidth));
		}
	}
	
	public void Remove() {
		data.remove(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		repository.deleteRecording(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		table.repaint();
	}

	public class MyTableModel extends AbstractTableModel {
		private String[] header;
		private Vector<Object[]> data;

		public MyTableModel(Vector<Object[]> data2, String[] header) {
			this.header = header;
			this.data = data2;
		}

		@Override
		public int getColumnCount() {
			if (header == null) {
				return 0;
			} else
				return header.length;
		}

		@Override
		public String getColumnName(int column) {
			return header[column];
		}

		@Override
		public int getRowCount() {
			return repository.getRecordings(EventRecording.class,true).size();
		}

		@Override
		public Object getValueAt(int row, int column) {
			if (column == 0 ) {
				return repository.getRecording(EventRecording.class,row,true).getName();
			} else if (column == 1 ) {
				return repository.getRecording(EventRecording.class,row,true).getRegexp();
			} else if (column == 2 ) {
				return repository.getRecording(EventRecording.class,row,true).getType();
			} else if (column == 3 ) {
				logger.debug("getvalueat name" + ((EventRecording) repository.getRecording(EventRecording.class, row,true)).getName());
				logger.debug("getvalueat is active" + source.isActiveRecordingOnSource(repository.getRecording(EventRecording.class, row,true)));
				return source.isActiveRecordingOnSource(repository.getRecording(EventRecording.class, row,true));
			}
			else return 0;
		}

		public void addRow(Object[] obj) {
			data.add(obj);
			//table.repaint();
		}

		public void updateRow(int rowId, Object[] obj) {
			data.set(rowId, obj);
			//table.repaint();
		}

		@Override
		public void setValueAt(Object value, int row, int column) {
			if (column == 3 && source != null) {
				logger.debug("setValueAt calls setActiveRecording");
				source.toggleActiveRecording(repository.getRecording(EventRecording.class, row,true));
				fireTableCellUpdated(row, column);
				// logger.debug("control of setValueAt: "+source.isActiveRecordingOnSource(repository.getRecording(MetadataRecording.class,
				// row)));
			} else {
				((Object[]) data.get(row))[column] = value;
					fireTableCellUpdated(row, column);
			}
			table.repaint();
		}

		/*
		 * @Override public void setValueAt(Object value, int row, int column) {
		 * data.get(row)[column] = value; fireTableCellUpdated(row, column); }
		 */
		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			// Note that the data/cell address is constant,
			// no matt&er where the cell appears onscreen.
			if (col > 2) {
				return true;
			} else {
				return false;
			}
		}
	}


/*	public void Add() {
		data.add(new Object[] { "", ".*", "long", Boolean.FALSE });
		table.repaint();
	}*/
}
 public class MetadataRecordingSelectorPanel extends JPanel {
	private static Logger logger = Logger.getLogger(MetadataRecordingSelectorPanel.class.getName());
	public static JTable table;
	JPanel jPanelDetail;
	boolean DEBUG = false;
	static Matcher m;
	static ArrayList records = null;
	private String[] header = { "name", "regexp", "type", "active" };
	private Vector<Object[]> data = new Vector<Object[]>();
	private Repository repository = null;
	private JPanel recEditor = null;
	public logdruid.ui.mainpanel.MetadataRecordingSelectorPanel.MyTableModel model;
	private Source source;

	/**
	 * Create the panel.
	 */
	public MetadataRecordingSelectorPanel(Repository rep, Source src) {
		repository = rep;
		source = src;
		records = rep.getRecordings(MetadataRecording.class,true);
		// Collections.sort(records);
		Iterator it = records.iterator();
		while (it.hasNext()) {
			Recording record = (Recording) it.next();
				data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), src.isActiveRecordingOnSource(record) });
			}
		
		model = new logdruid.ui.mainpanel.MetadataRecordingSelectorPanel.MyTableModel(data, header);

		logger.debug("source is " + ((source == null) ? "null" : src.getSourceName()));
		setLayout(new BorderLayout(0, 0));

		JPanel panel_1 = new JPanel();
		panel_1.setLayout(new BorderLayout(0, 0));
		panel_1.setMinimumSize(new Dimension(0,150));
		table = new JTable(model);
		JScrollPane scrollPane = new JScrollPane(table);
		panel_1.add(scrollPane, BorderLayout.CENTER);

		table.setPreferredScrollableViewportSize(new Dimension(0, 150));
		table.setFillsViewportHeight(true);
		table.setAutoCreateRowSorter(true);

		// Set up column sizes.
		initColumnSizes(table);
		reloadTable();

		JSplitPane splitPane = new JSplitPane();
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		add(splitPane);

		jPanelDetail = new JPanel();
		splitPane.setBottomComponent(jPanelDetail);
		splitPane.setTopComponent(panel_1);

		jPanelDetail.setLayout(new BorderLayout(0, 0));
		table.getModel().addTableModelListener(new TableModelListener(){
			 public void tableChanged(TableModelEvent e) {
			        int row = e.getFirstRow();
			        int column = e.getColumn();
			        if (column!= -1){
			        TableModel model = (TableModel)e.getSource();
			        String columnName = model.getColumnName(column);
			        Object data = model.getValueAt(row, column);
			        if (e.getColumn()==3)
			        {
			        	source.setActiveMetadata((MetadataRecording)repository.getRecording(MetadataRecording.class, row,true));
			        }
					int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);

					logger.debug("ListSelectionListener - selectedRow: " + selectedRow);
					if (selectedRow >= 0) {

						if (jPanelDetail != null) {
							logger.debug("ListSelectionListener - valueChanged");
							jPanelDetail.removeAll();
							recEditor = getEditor(repository.getRecording(MetadataRecording.class, selectedRow,true));
							if (recEditor != null) {
								jPanelDetail.add(recEditor, BorderLayout.CENTER);
							}
							reloadTable();
							jPanelDetail.revalidate();
						}
					}
			    }}
			{
		}
		});
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			public void valueChanged(ListSelectionEvent e) {
				// ((table.getSelectedRow()!=-1)?table.convertRowIndexToModel(table.getSelectedRow()):-1)
				// persist repository
				// display selected row
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);

				logger.debug("ListSelectionListener - selectedRow: " + selectedRow);
				if (selectedRow >= 0) {

					if (jPanelDetail != null) {
						logger.debug("ListSelectionListener - valueChanged");
						jPanelDetail.removeAll();
						recEditor = getEditor(repository.getRecording(MetadataRecording.class, selectedRow,true));
						if (recEditor != null) {
							jPanelDetail.add(recEditor, BorderLayout.CENTER);
						}
						reloadTable();
						jPanelDetail.revalidate();
					}
				}
			}
		});
		
		if (repository.getRecordings(MetadataRecording.class,true).size() > 0) {
			recEditor = getEditor(repository.getRecording(MetadataRecording.class,0,true));
			jPanelDetail.add(recEditor, BorderLayout.CENTER);

		}
		if (model.getRowCount()>0 && (source.getActiveMetadata()!=null)){
			table.getRowSorter().toggleSortOrder(0);
			table.setRowSelectionInterval(0, 0);
			 ArrayList records = rep.getRecordings(MetadataRecording.class,true);
			table.setRowSelectionInterval(table.convertRowIndexToView(records.indexOf(source.getActiveMetadata())),table.convertRowIndexToView(records.indexOf(source.getActiveMetadata())));
		}
		//reloadTable();
		// jPanelDetail.revalidate();

	}

	private JPanel getEditor(Recording rec) {
		return new MetadataRecordingEditor(this,repository, rec.getExampleLine(), rec.getRegexp(), ((MetadataRecording) rec),source);
	}

	public void reloadTable() {
		int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
		records = repository.getRecordings(MetadataRecording.class,true);
		logger.debug("reloadTable - nb records : " + records.size());
		Iterator it = records.iterator();
		int count = 0;
		data.clear();
		// this.repaint();

		logger.debug("reloadTable - 1");
		while (it.hasNext()) {
			Boolean bool = false;
			Recording record = (Recording) it.next();
			if (source != null) {
				bool = source.isActiveRecordingOnSource(record);
				logger.debug("ReloadTable with " + record.getName() + " with isActiveRecordingOnSource: " + source.isActiveRecordingOnSource(record));
			}
			data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), bool });
			logger.debug("name: " + record.getName() + "regexp: " + record.getRegexp() + "isActive: " + record.getIsActive());
		}
		logger.debug("reloadTable - 2");
		// this.repaint();
		table.repaint();

		logger.debug("reloadTable - 3");
		this.revalidate();

	}

	private void initColumnSizes(JTable theTable) {
		MyTableModel model = (MyTableModel) theTable.getModel();
		TableColumn column = null;
		Component comp = null;
		int headerWidth = 0;
		int cellWidth = 0;
		// Object[] longValues = model.longValues;
		TableCellRenderer headerRenderer = theTable.getTableHeader().getDefaultRenderer();

		for (int i = 0; i < 4; i++) {
			column = theTable.getColumnModel().getColumn(i);
			comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
			headerWidth = comp.getPreferredSize().width;
			cellWidth = comp.getPreferredSize().width;
			column.setPreferredWidth(Math.max(headerWidth, cellWidth));
		}
	}

	public class MyTableModel extends AbstractTableModel {
		private String[] header;
		private Vector<Object[]> data;

		public MyTableModel(Vector<Object[]> data2, String[] header) {
			this.header = header;
			this.data = data2;
		}

		@Override
		public int getColumnCount() {
			if (header == null) {
				return 0;
			} else
				return header.length;
		}

		@Override
		public String getColumnName(int column) {
			return header[column];
		}

		@Override
		public int getRowCount() {
			return repository.getRecordings(MetadataRecording.class,true).size();
		}

		@Override
		public Object getValueAt(int row, int column) {
			if (column == 0 ) {
				return repository.getRecording(MetadataRecording.class,row,true).getName();
			} else if (column == 1 ) {
				return repository.getRecording(MetadataRecording.class,row,true).getRegexp();
			} else if (column == 2 ) {
				return repository.getRecording(MetadataRecording.class,row,true).getType();
			} else if (column == 3 ) {
				return source.getActiveMetadata()==(repository.getRecording(MetadataRecording.class, row,true));
			}
			else return 0;
		}

		public void addRow(Object[] obj) {
			data.add(obj);
		}

		public void updateRow(int rowId, Object[] obj) {
			data.set(rowId, obj);
			}

		@Override
		public void setValueAt(Object value, int row, int column) {
			if (column == 3 && source != null) {
				logger.debug("setValueAt calls setActiveRecording");
				source.setActiveMetadata((MetadataRecording)repository.getRecording(MetadataRecording.class, row,true));
				data.get(row)[column] = value;
				fireTableCellUpdated(row, column);
				// logger.debug("control of setValueAt: "+source.isActiveRecordingOnSource(repository.getRecording(MetadataRecording.class,
				// row)));
			} else {
				data.get(row)[column] = value;
				fireTableCellUpdated(row, column);
			}
			table.repaint();
		}

		/*
		 * @Override public void setValueAt(Object value, int row, int column) {
		 * data.get(row)[column] = value; fireTableCellUpdated(row, column); }
		 */
		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			// Note that the data/cell address is constant,
			// no matt&er where the cell appears onscreen.
			if (col > 2) {
				return true;
			} else {
				return false;
			}
		}

		/*
		 * Don't need to implement this method unless your table's data can
		 * change.
		 */

		/*
		 * public void setValueAt(Object value, int row, int col) { if (DEBUG) {
		 * logger.debug("Setting value at " + row + "," + col + " to " + value +
		 * " (an instance of " + value.getClass() + ")"); } if(4 == col) {}
		 * 
		 * }
		 */
		/*
		 * data[row][col] = value; fireTableCellUpdated(row, col);
		 * 
		 * if (DEBUG) { logger.debug("New value of data:"); printDebugData(); } }
		 * 
		 * private void printDebugData() { int numRows = getRowCount(); int
		 * numCols = getColumnCount();
		 * 
		 * for (int i=0; i < numRows; i++) { System.out.print("    row " + i +
		 * ":"); for (int j=0; j < numCols; j++) { System.out.print("  " +
		 * data[i][j]); } logger.debug(); }
		 * logger.debug("--------------------------"); }
		 */
	}

	/*
	 * public ArrayList<RecordingItem> getRecordingItems() {
	 * ArrayList<RecordingItem> toReturn = new ArrayList<RecordingItem>(); for
	 * (int i = 0; i < data.size(); i++) { // model.getRowCount()
	 * toReturn.add(new RecordingItem((String) model.getValueAt(i, 0), (String)
	 * model.getValueAt(i, 1), (String) model.getValueAt(i, 2), (String) model
	 * .getValueAt(i, 3), (Boolean) model.getValueAt(i, 4), (String)
	 * model.getValueAt(i, 5))); } return toReturn; }
	 */

	public void Add() {
		data.add(new Object[] { "", ".*", "long", Boolean.FALSE });
		table.repaint();
	}

	public void Remove() {
		data.remove(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		table.repaint();
	}
}
 public class PreferencePanel extends JPanel {
	private static Logger logger = Logger.getLogger(EventRecordingSelectorPanel.class.getName());
	private JTextField textField;

	/**
	 * Create the panel.
	 * @param repository 
	 */
	public PreferencePanel(final Repository repository) {
		setLayout(new BorderLayout(0, 0));
		final JPanel panel_1 = new JPanel();
		panel_1.setLayout(new BorderLayout());
		JPanel panel_2 = new JPanel();
		add(panel_2, BorderLayout.EAST);
		
		//HashMap<String, String> 
		if (Preferences.getPreferences()!=null){
		SortedSet<String> prefSet = new TreeSet<String>();
		prefSet.addAll(Preferences.getPreferences().keySet());
		Iterator ite = prefSet.iterator();
		
		while (ite.hasNext()){
			String key=(String) ite.next();
			JPanel panel = new JPanel();
			panel.setLayout(new BorderLayout());
			panel_1.add(panel,BorderLayout.LINE_START);
			panel.setMaximumSize(new Dimension(600, 20));
			JLabel lblKey = new JLabel(key);
			panel.add(lblKey,BorderLayout.WEST);
			textField = new JTextField();
			panel.add(textField);
			textField.setColumns(30);
			textField.setText(Preferences.getPreference(key));
		}
		}
		JButton btnSave = new JButton("Save");
		btnSave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Component[] comp=panel_1.getComponents();
				int i=0;
				logger.debug(Preferences.getPreferences());
				while (i<comp.length-1){
					logger.debug(((JLabel)((JPanel)comp[i]).getComponents()[0]).getText()+" = "+((JTextField)((JPanel)comp[i]).getComponents()[1]).getText());
					Preferences.setPreference(((JLabel)((JPanel)comp[i]).getComponents()[0]).getText(), ((JTextField)((JPanel)comp[i]).getComponents()[1]).getText());
					i++;
				}
				Preferences.persist();
			}
		});
		WrapLayout wl_panel_2 = new WrapLayout(WrapLayout.LEFT, 5, 5);
		wl_panel_2.setAlignment(FlowLayout.CENTER);
		panel_2.setLayout(wl_panel_2);
		panel_2.add(btnSave);

		add(panel_1, BorderLayout.CENTER);
		panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.PAGE_AXIS));
		
		JPanel panel = new JPanel();
		panel.setMinimumSize(new Dimension(50,0));
		panel_1.add(panel, BorderLayout.WEST);
		
		JPanel panel_3 = new JPanel();
		panel_3.setMinimumSize(new Dimension(0,40));
		add(panel_3, BorderLayout.NORTH);

	}
} public class RecordingList extends JPanel {
	private static Logger logger = Logger.getLogger(DataMiner.class.getName());
	public static JTable table;
	JPanel jPanelDetail;
	private RecordingList thiis = this;
	boolean DEBUG = false;
	static Matcher m;
	static ArrayList records = null;
	private String[] header ;
	// 0-> sum of time for success matching of given
	// recording ; 1-> sum of time for failed
	// matching ; 2-> count of match attempts,
	// 3->count of success attempts
	private Vector<Object[]> data = new Vector<Object[]>();
	private Repository repository = null;
	private JPanel recEditor = null;
	public MyTableModel2 model;
	long[] stats;
	
	/**
	 * Create the panel.
	 */
	public RecordingList(final Repository rep) {
		
		if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("true") ) {
			header = (String[]) new String[] { "name", "regexp", "type", "active", "success time", "failed time", "match attempt", "success match" };
		} else if (Preferences.getPreference("timings").equals("false") && Preferences.getPreference("matches").equals("true") ) {
			header = (String[]) new String[] { "name", "regexp", "type", "active", "match attempt", "success match"  };
		} else if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("false") ) {
			header = (String[]) new String[] { "name", "regexp", "type", "active" ,"success time", "failed time", };
		} else {
			header = (String[]) new String[] { "name", "regexp", "type", "active" };
		}
	
		records = rep.getRecordings();
		// Collections.sort(records);
		Iterator it = records.iterator();
		while (it.hasNext()) {
			Recording record = (Recording) it.next();
			logger.debug("about to call DataVault.getRecordingStats on :"+record.getName());
			stats = DataVault.getRecordingStats(record.getName());
			if (stats != null) {
				if (Preferences.getPreference("timings").equals("false") && Preferences.getPreference("matches").equals("true") ) {
				data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), stats[2],
						stats[3] });
				} else if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("false") ) {
				data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), stats[0], stats[1]});
				} else if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("true") ) {
					data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), stats[0], stats[1], stats[2],
							stats[3] });
					} 
			} else {
				data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), 0, 0, 0, 0 });
			}
		}
		
		
		repository = rep;
		model = new MyTableModel2(data, header);

		JPanel panel_1 = new JPanel();
		GridBagConstraints gbc_panel_1 = new GridBagConstraints();
		gbc_panel_1.fill = GridBagConstraints.BOTH;
		gbc_panel_1.insets = new Insets(5, 0, 5, 5);
		gbc_panel_1.gridx = 1;
		gbc_panel_1.gridy = 0;
		panel_1.setLayout(new BorderLayout(0, 0));

		table = new JTable(model);
		JScrollPane scrollPane = new JScrollPane(table);int column;
		panel_1.add(scrollPane);

		table.setPreferredScrollableViewportSize(new Dimension(0, 150));
		table.setFillsViewportHeight(true);

		// Set up column sizes.
		initColumnSizes(table);
		table.setAutoCreateRowSorter(true);
	//	RowSorter sorter = table.getRowSorter();
//		sorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
		if (model.getRowCount()>0){
			table.getRowSorter().toggleSortOrder(0);
		table.getRowSorter().toggleSortOrder(2);
		}
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			public void valueChanged(ListSelectionEvent e) {
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
				;
				logger.debug("ListSelectionListener - selectedRow: " + selectedRow);
				if (selectedRow >= 0) {
					if (jPanelDetail != null) {
						logger.debug("ListSelectionListener - valueChanged");
						jPanelDetail.removeAll();
						recEditor = getEditor(repository.getRecording(selectedRow));
						if (recEditor != null) {
							jPanelDetail.add(recEditor, BorderLayout.CENTER);
						}
						jPanelDetail.revalidate();
					}
				}
			}
		});
		JPanel panel = new JPanel();
		FlowLayout flowLayout = (FlowLayout) panel.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);
		flowLayout.setVgap(2);
		flowLayout.setHgap(2);
		panel_1.add(panel, BorderLayout.SOUTH);

		JButton btnNewMeta = new JButton("New File Grouping");
		panel.add(btnNewMeta);
		btnNewMeta.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				int rowCount = table.getRowCount();
				jPanelDetail.removeAll();
				Recording re = new MetadataRecording("name", "regex", "example line", "", true, true, null);
				recEditor = new MetadataRecordingEditor(thiis, repository, "the line", "regex",	(MetadataRecording) re,null);
				jPanelDetail.add(recEditor, BorderLayout.CENTER);
				repository.addRecording(re);
				model.addRow(new Object[] { re.getName(), re.getRegexp(), re.getType(), re.getIsActive(), 0, 0, 0, 0 });
				model.fireTableRowsInserted(rowCount, rowCount);
				table.setRowSelectionInterval(rowCount, rowCount);
				logger.debug("New record - row count : " + rowCount);
			}
		});

		JButton btnDuplicate = new JButton("Duplicate");
		btnDuplicate.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int rowCount = table.getRowCount();
				int selectRow = ((table.getSelectedRow() != -1) ? table.getSelectedRow() : -1);
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
				rep.duplicateRecording(table.convertRowIndexToModel(table.getSelectedRow()));
				model.fireTableRowsInserted(rowCount, rowCount);
				table.setRowSelectionInterval(selectRow+1, selectRow+1);
			}
		});

		JButton btnNewStat = new JButton("New Stat");
		btnNewStat.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int rowCount = table.getRowCount();
				jPanelDetail.removeAll();
				Recording re = new StatRecording("name", "regex", "example line", "", true,true, true, null);
				recEditor = new StatRecordingEditor(thiis, repository, "the line", "regex", (StatRecording) re);
				jPanelDetail.add(recEditor, BorderLayout.CENTER);
				repository.addRecording(re);
				model.addRow(new Object[] { re.getName(), re.getRegexp(), re.getType(), re.getIsActive(), 0, 0, 0, 0 });
				model.fireTableRowsInserted(rowCount, rowCount);
				table.setRowSelectionInterval(rowCount, rowCount);
				logger.debug("New record - row count : " + rowCount);
			}
		});
		panel.add(btnNewStat);

		JButton btnNewEvent = new JButton("New Event");
		btnNewEvent.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int rowCount = table.getRowCount();
				logger.debug("table.getRowCount()" + table.getRowCount());
				jPanelDetail.removeAll();
				Recording re = new EventRecording("name", "regex", "example line", "", true, true, true, null);
				recEditor = new EventRecordingEditor(thiis, repository, "the line", "regex", (EventRecording) re);
				jPanelDetail.add(recEditor, BorderLayout.CENTER);
				repository.addRecording(re);
				model.addRow(new Object[] { re.getName(), re.getRegexp(), re.getType(), re.getIsActive(), 0, 0, 0, 0 });
				model.fireTableRowsInserted(rowCount, rowCount);
				table.setRowSelectionInterval(rowCount, rowCount);
				logger.debug("New record - row count : " + rowCount);
			}
		});
		panel.add(btnNewEvent);
		JButton btnNewReport = new JButton("New Report");
		btnNewReport.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int rowCount = table.getRowCount();
				logger.debug("table.getRowCount()" + table.getRowCount());
				jPanelDetail.removeAll();
				Recording re = new ReportRecording("name", "regex", "example line", "", true, true, null,"histogram",true);
				recEditor = new ReportRecordingEditor(thiis, repository, "the line", "regex", (ReportRecording) re, "histogram");
				jPanelDetail.add(recEditor, BorderLayout.CENTER);
				repository.addRecording(re);
				model.addRow(new Object[] { re.getName(), re.getRegexp(), re.getType(), re.getIsActive(), 0, 0, 0, 0 });
				model.fireTableRowsInserted(rowCount, rowCount);
				table.setRowSelectionInterval(rowCount, rowCount);
				logger.debug("New record - row count : " + rowCount);
			}
		});
		panel.add(btnNewReport);
		panel.add(btnDuplicate);

		JButton btnDelete = new JButton("Delete");
		btnDelete.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int rowCount = table.getRowCount();
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
				;
				int realSelectedRow=table.getSelectedRow() ;
				logger.debug("selectedRow : " + selectedRow + ", row count: " + table.getRowCount());
				if (rowCount!=0){
				repository.deleteRecording(selectedRow);
				model.fireTableRowsDeleted(selectedRow, selectedRow);
	//			table.remove(selectedRow);
				if (realSelectedRow!= -1){
					if (realSelectedRow!= 0)table.setRowSelectionInterval(realSelectedRow-1, realSelectedRow-1);
					else if (realSelectedRow >0)table.setRowSelectionInterval(realSelectedRow, realSelectedRow);
					else if (rowCount>1) table.setRowSelectionInterval(0, 0);
				}
/*				if (table.getRowCount() > 0) {
					if (selectedRow == table.getRowCount()) {
						table.setRowSelectionInterval(selectedRow - 1, selectedRow - 1);
					} else
						table.setRowSelectionInterval(selectedRow, selectedRow);
				}*/
			}}
		});
		panel.add(btnDelete);
		setLayout(new BorderLayout(0, 0));

		JSplitPane splitPane = new JSplitPane();
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		add(splitPane, BorderLayout.CENTER);

		jPanelDetail = new JPanel();
		GridBagConstraints gbc_jPanelDetail = new GridBagConstraints();
		gbc_jPanelDetail.insets = new Insets(0, 0, 0, 5);
		gbc_jPanelDetail.fill = GridBagConstraints.BOTH;
		gbc_jPanelDetail.gridx = 1;
		gbc_jPanelDetail.gridy = 4;
		splitPane.setBottomComponent(jPanelDetail);
		splitPane.setTopComponent(panel_1);
		jPanelDetail.setLayout(new BorderLayout(0, 0));
		if (repository.getRecordingCount() > 0) {
			//recEditor = getEditor(repository.getRecording(0));
			//jPanelDetail.add(recEditor, BorderLayout.CENTER);
			table.setRowSelectionInterval(0, 0);
		}
		jPanelDetail.revalidate();

	}

	private JPanel getEditor(Recording rec) {
		JPanel editorPanel = null;
		if (rec.getClass() == StatRecording.class) {
			editorPanel = new StatRecordingEditor(thiis, repository, rec.getExampleLine(), rec.getRegexp(), ((StatRecording) rec));
		} else if (rec.getClass() == MetadataRecording.class) {
			editorPanel = new MetadataRecordingEditor(thiis, repository, rec.getExampleLine(), rec.getRegexp(),
					((MetadataRecording) rec),null);
		} else if (rec.getClass() == EventRecording.class) {
			editorPanel = new EventRecordingEditor(thiis, repository, rec.getExampleLine(), rec.getRegexp(), ((EventRecording) rec));
		} else if (rec.getClass() == ReportRecording.class) {
			editorPanel = new ReportRecordingEditor(thiis, repository, rec.getExampleLine(), rec.getRegexp(), ((ReportRecording) rec), ((ReportRecording) rec).getSubType());
		}
		return editorPanel;
	}

	private void initColumnSizes(JTable theTable) {
		MyTableModel2 model = (MyTableModel2) theTable.getModel();
		TableColumn column = null;
		Component comp = null;
		int headerWidth = 0;
		int cellWidth = 0;
		// Object[] longValues = model.longValues;
		TableCellRenderer headerRenderer = theTable.getTableHeader().getDefaultRenderer();

		for (int i = 0; i < 4; i++) {
			column = theTable.getColumnModel().getColumn(i);
			comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
			headerWidth = comp.getPreferredSize().width;
			cellWidth = comp.getPreferredSize().width;
			column.setPreferredWidth(Math.max(headerWidth, cellWidth));
		}
	}

	public  class MyTableModel2 extends AbstractTableModel {
		private String[] header;
		 private Vector data = new Vector();
		 
		public MyTableModel2(Vector<Object[]> data, String[] header) {
			this.header = header;
			this.data = data;
		}

		@Override
		public int getColumnCount() {
			if (header == null) {
				return 0;
			} else
				return header.length;
		}

		@Override
		public String getColumnName(int column) {
			return header[column];
		}

		@Override
		public int getRowCount() {
			return repository.getRecordingCount();
		}
		
		public void addRow(Object[] obj) {
			data.add(obj);
		}

		public void updateRow(int rowId, Object[] obj) {
			data.set(rowId, obj);
		}

		@Override
		public Object getValueAt(int row, int column) {
			if (column == 0 ) {
				return repository.getRecording(row).getName();
			} else if (column == 1 ) {
				return repository.getRecording(row).getRegexp();
			} else if (column == 2 ) {
				return repository.getRecording(row).getType();
			} else if (column == 3 ) {
				logger.debug("setValueAt calls setActiveRecording");
				return repository.getRecording(row).getIsActive();
			} else if (column >3 && column<9) {
				stats = DataVault.getRecordingStats(repository.getRecording(row).getName());
				if (stats != null) {
					if (Preferences.getPreference("timings").equals("false") && Preferences.getPreference("matches").equals("true") ) {
						return stats[column - 2];
					} else {
						return stats[column - 4];
						} 
				} else return 0;
			}
			else return 0;

		}

		@Override
		public void setValueAt(Object value, int row, int column) {
		
			if (column == 3 ) {
				logger.debug("setValueAt calls setActiveRecording");
				repository.getRecording(row).setIsActive((Boolean)value);
				//.toggleActiveRecording(repository.getRecording(MetadataRecording.class, row));
				fireTableCellUpdated(row, column);
				// logger.debug("control of setValueAt: "+source.isActiveRecordingOnSource(repository.getRecording(MetadataRecording.class,
				// row)));
			} else {
				((Object[]) data.get(row))[column] = value;
				//	logger.debug("setValueAt"+row+","+column);
					fireTableCellUpdated(row, column);
			}
		}

		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			// Note that the data/cell address is constant,
			// no matt&er where the cell appears onscreen.
			if (col != 3) {
				return false;
			} else {
				return true;
			}
		}

		
		/*
		 * Don't need to implement this method unless your table's data can
		 * change.
		 */
		/*
		 * public void setValueAt(Object value, int row, int col) { if (DEBUG) {
		 * logger.debug("Setting value at " + row + "," + col + " to " + value +
		 * " (an instance of " + value.getClass() + ")"); }
		 * 
		 * data[row][col] = value; fireTableCellUpdated(row, col);
		 * 
		 * if (DEBUG) { logger.debug("New value of data:"); printDebugData(); } }
		 * 
		 * private void printDebugData() { int numRows = getRowCount(); int
		 * numCols = getColumnCount();
		 * 
		 * for (int i=0; i < numRows; i++) { System.out.print("    row " + i +
		 * ":"); for (int j=0; j < numCols; j++) { System.out.print("  " +
		 * data[i][j]); } logger.debug(); }
		 * logger.debug("--------------------------"); }
		 */
	}

	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event-dispatching thread.
	 * 
	 * private static void createAndShowGUI() { // Create and set up the window.
	 * JFrame frame = new JFrame("RecordingEditorTable");
	 * frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	 * 
	 * // Create and set up the content pane. ReportPanel newContentPane = new
	 * ReportPanel(null, repository); newContentPane.setOpaque(true); //
	 * content panes must be opaque frame.setContentPane(newContentPane);
	 * 
	 * // Display the window. frame.pack(); frame.setVisible(true); }
	 */

	/*
	 * public ArrayList<RecordingItem> getRecordingItems() {
	 * ArrayList<RecordingItem> toReturn = new ArrayList<RecordingItem>(); for
	 * (int i = 0; i < data.size(); i++) { // model.getRowCount()
	 * toReturn.add(new RecordingItem((String) model.getValueAt(i, 0),(String)
	 * model.getValueAt(i, 1), (String) model.getValueAt(i, 2), (Boolean)
	 * model.getValueAt(i, 3)); } return toReturn; }
	 */

	/*
	 * public void Add() { data.add(new Object[] { " ", "", "long", "",
	 * Boolean.TRUE, "" }); table.repaint(); }
	 */

	public void Remove() {
		data.remove(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		repository.deleteRecording(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		table.repaint();
	}
}
 public class ReportPanel extends JPanel {
	private static Logger logger = Logger.getLogger(DataMiner.class.getName());
	public static JTable reportList;
	JPanel jPanelDetail;
	private ReportPanel thiis = this;
	boolean DEBUG = false;
	static Matcher m;
	static ArrayList records = null;
	private String[] header;
	private String[] headerRecords;
	// 0-> sum of time for success matching of given
	// recording ; 1-> sum of time for failed
	// matching ; 2-> count of match attempts,
	// 3->count of success attempts
	private Vector<Object[]> data = new Vector<Object[]>();
	private Repository repository = null;
	private JPanel recEditor = null;
	public MyTableModel2 model;
	public RecordReportTableModel recordReportTableModel;
	long[] stats;
	private JTable reportDetails;
	private Map<List<Object>, Long> occurenceReportMap;
	private Map<List<Object>, Double> sumReportMap;
	private SortedMap<Double,List<Object>> top100ReportMap;
	private MineResultSet mineResultSet;

	/**
	 * Create the panel.
	 */
	public ReportPanel(final Repository rep, final MineResultSet mineResultSet1) {

		if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("true") ) {
			header = (String[]) new String[] { "name", "regexp", "type", "rows", "success time", "failed time", "match attempt", "success match" };
		} else if (Preferences.getPreference("timings").equals("false") && Preferences.getPreference("matches").equals("true") ) {
			header = (String[]) new String[] { "name", "regexp", "type", "rows", "match attempt", "success match"  };
		} else if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("false") ) {
			header = (String[]) new String[] { "name", "regexp", "type", "rows" ,"success time", "failed time", };
		} else {
			header = (String[]) new String[] { "name", "regexp", "type", "rows" };
		}
		mineResultSet=mineResultSet1;
		records = rep.getReportRecordings(mineResultSet1,true);
		Iterator it = records.iterator();
		while (it.hasNext()) {
			Recording record = (Recording) it.next();
			logger.debug("Report panel load:"+record.getName());
			stats = DataVault.getRecordingStats(record.getName());
			if (record.getIsActive() ) {
				//&& ((Map<Recording, Map<List<Object>, Long>>)(mineResultSet1.getOccurenceReport().values())).get(record).size()>0
				logger.debug(record.getName());
				if (stats != null) {
					if (Preferences.getPreference("timings").equals("false") && Preferences.getPreference("matches").equals("true") ) {
					data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), stats[2],
							stats[3] });
					} else if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("false") ) {
					data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), stats[0], stats[1]});
					} else if (Preferences.getPreference("timings").equals("true") && Preferences.getPreference("matches").equals("true") ) {
						data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), stats[0], stats[1], stats[2],
								stats[3] });
						} 
				} else {
					data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive(), 0, 0, 0, 0 });
				}
			}
		}
		repository = rep;
		model = new MyTableModel2(data, header,mineResultSet);
		JPanel panel_1 = new JPanel();
		panel_1.setMinimumSize(new Dimension(0, 150));
		GridBagConstraints gbc_panel_1 = new GridBagConstraints();
		gbc_panel_1.fill = GridBagConstraints.BOTH;
		gbc_panel_1.insets = new Insets(5, 0, 5, 5);
		gbc_panel_1.gridx = 1;
		gbc_panel_1.gridy = 0;
		panel_1.setLayout(new BorderLayout(0, 0));
		reportList = new JTable(model);
		reportList.setPreferredScrollableViewportSize(new Dimension(0, 150));
		reportList.setFillsViewportHeight(true);
		// Set up column sizes.
		initColumnSizes(reportList);
		reportList.setAutoCreateRowSorter(true);
		// RowSorter sorter = table.getRowSorter();
		// sorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(0,
		// SortOrder.ASCENDING)));
		if (model.getRowCount() > 0) {
			reportList.getRowSorter().toggleSortOrder(2);
			reportList.getRowSorter().toggleSortOrder(0);
		}
		reportList.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			public void valueChanged(ListSelectionEvent e) {
				int selectedRow = ((reportList.getSelectedRow() != -1) ? reportList.convertRowIndexToModel(reportList.getSelectedRow()) : -1);
				logger.debug("ListSelectionListener - selectedRow: " + selectedRow);
				ArrayList<List<Object>> data1 = new ArrayList<List<Object>>();
				ArrayList<Object[]> rIArrayList = new ArrayList<Object[]>();
				if (selectedRow >= 0 )  {
					if ((((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(selectedRow)).getSubType().equals("histogram"))
					{
					Iterator<RecordingItem> rIIte = (((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(selectedRow)).getRecordingItem().iterator();
					rIArrayList.add(new Object[] { "Source", String.class });
					while (rIIte.hasNext()) {
						RecordingItem ri = (RecordingItem) rIIte.next();
						Class c = String.class;
						if (ri.isSelected()) {
							if (ri.getType().equals("string") || ri.getType().equals("stringminimum") || ri.getType().equals("word") || ri.getType().equals("date")) {
								c = String.class;
							} else if (ri.getType().equals("long")) {
								c = Long.class;
							} else if (ri.getType().equals("double")) {
								c = double.class;
							}
							rIArrayList.add(new Object[] { ri.getName(), c });
						}
					}
					rIArrayList.add(new Object[] { "count", Long.class });
					
					if (mineResultSet1.getOccurenceReport() != null) {
						Iterator sourcesIterator=rep.getSources().iterator();
						while (sourcesIterator.hasNext())
						{
							Source src=(Source) sourcesIterator.next();
							if (src.getActive()  && mineResultSet1.getOccurenceReport().containsKey(src)){
						occurenceReportMap = mineResultSet1.getOccurenceReport().get(src).get((((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(selectedRow)));
						if (occurenceReportMap != null) {
							Iterator<List<Object>> oRMIte = occurenceReportMap.keySet().iterator();
							while (oRMIte.hasNext()) {
								List<Object> obj = new ArrayList<Object>();
								List<Object> tempObj=oRMIte.next();
								obj.add(src.getSourceName());
								obj.addAll(1, tempObj);
								obj.add(occurenceReportMap.get(tempObj));
								data1.add(obj);
							}
							// logger.info(""+headerRecords.length
							// +Arrays.deepToString(headerRecords));
						}}
						}
						recordReportTableModel = new RecordReportTableModel(data1, rIArrayList);
						reportDetails = new JTable(recordReportTableModel);
					}
					
					}
					else if ((((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(selectedRow)).getSubType().equals("top100"))
					{
						Iterator<RecordingItem> rIIte = (((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(selectedRow)).getRecordingItem().iterator();
						rIArrayList.add(new Object[] { "Source", String.class });
						while (rIIte.hasNext()) {
							RecordingItem ri = (RecordingItem) rIIte.next();
							Class c = null;
							if (ri.isSelected() && ri.getProcessingType().equals("capture")) {
								if (ri.getType().equals("string") || ri.getType().equals("stringminimum") || ri.getType().equals("word") || ri.getType().equals("date")) {
									c = String.class;
								} else if (ri.getType().equals("long")) {
									c = Long.class;
								} else if (ri.getType().equals("double")) {
									c = double.class;
								}
								rIArrayList.add(new Object[] { ri.getName(), c });
							}
						}
						rIArrayList.add(new Object[] { "value", Double.class });	
						if (mineResultSet1.getTop100Report() != null) {
							Iterator sourcesIterator=rep.getSources().iterator();
							while (sourcesIterator.hasNext())
							{
								Source src=(Source) sourcesIterator.next();
								if (src.getActive()  && mineResultSet1.getTop100Report().containsKey(src)){
									top100ReportMap = mineResultSet1.getTop100Report().get(src).get((((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(selectedRow)));
							if (top100ReportMap != null) {
								Iterator<Double> oRMIte = top100ReportMap.keySet().iterator();
								while (oRMIte.hasNext()) {
									List<Object> obj = new ArrayList<Object>();
									Double tempObj=oRMIte.next();
									obj.add(src.getSourceName());
									obj.addAll(1, top100ReportMap.get(tempObj));
									obj.add(tempObj);
									data1.add(obj);
								}
								// logger.info(""+headerRecords.length
								// +Arrays.deepToString(headerRecords));
							}}
							}
							recordReportTableModel = new RecordReportTableModel(data1, rIArrayList);
							reportDetails = new JTable(recordReportTableModel);
						}
					}
					
					else if ((((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(selectedRow)).getSubType().equals("sum"))
					{
						Iterator<RecordingItem> rIIte = (((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(selectedRow)).getRecordingItem().iterator();
						rIArrayList.add(new Object[] { "Source", String.class });
						while (rIIte.hasNext()) {
							RecordingItem ri = (RecordingItem) rIIte.next();
							Class c = null;
							if (ri.isSelected() && ri.getProcessingType().equals("capture")) {
								if (ri.getType().equals("string") || ri.getType().equals("stringminimum") || ri.getType().equals("word") || ri.getType().equals("date")) {
									c = String.class;
								} else if (ri.getType().equals("long")) {
									c = Long.class;
								} else if (ri.getType().equals("double")) {
									c = double.class;
								}
								rIArrayList.add(new Object[] { ri.getName(), c });
							} else if (ri.isSelected() && ri.getProcessingType().equals("sum")){
								c = Double.class;
								rIArrayList.add(new Object[] { "sum of "+ ri.getName(), c });
							}
						}	
						if (mineResultSet1.getSumReport() != null) {
							Iterator sourcesIterator=rep.getSources().iterator();
							while (sourcesIterator.hasNext())
							{
								Source src=(Source) sourcesIterator.next();
								if (src.getActive()  && mineResultSet1.getSumReport().containsKey(src)){
									sumReportMap = mineResultSet1.getSumReport().get(src).get((((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(selectedRow)));
							if (sumReportMap != null) {
								Iterator<List<Object>> oRMIte = sumReportMap.keySet().iterator();
								while (oRMIte.hasNext()) {
									List<Object> obj = new ArrayList<Object>();
									List<Object> tempObj=oRMIte.next();
									obj.add(src.getSourceName());
									obj.addAll(1, tempObj);
									obj.add(sumReportMap.get(tempObj));
									data1.add(obj);
								}
								// logger.info(""+headerRecords.length
								// +Arrays.deepToString(headerRecords));
							}}
							}
							recordReportTableModel = new RecordReportTableModel(data1, rIArrayList);
							reportDetails = new JTable(recordReportTableModel);
						}
					}
					// headerRecords=(String[]) rIArrayList.toArray(new
					// String[rIArrayList.size()]);

					// logger.info(""+headerRecords.length +headerRecords);

				}

				// logger.info(mineResultSet1.getOccurenceReport().values());
				// logger.info(repository.getRecording(ReportRecording.class,selectedRow));
				reportDetails.setPreferredScrollableViewportSize(new Dimension(0, 150));
				reportDetails.setFillsViewportHeight(true);
				reportDetails.setAutoCreateRowSorter(true);
if (reportDetails.getColumnCount()>1){
				reportDetails.getRowSorter().toggleSortOrder(reportDetails.getColumnCount() - 1);
				reportDetails.getRowSorter().toggleSortOrder(reportDetails.getColumnCount() - 1);
}
				if (reportDetails != null) {
					jPanelDetail.removeAll();
					JScrollPane scrollPane_1 = new JScrollPane(reportDetails);
					jPanelDetail.add(scrollPane_1, BorderLayout.CENTER);
				}
				jPanelDetail.revalidate();
			}

		});
		JPanel panel = new JPanel();
		FlowLayout flowLayout = (FlowLayout) panel.getLayout();
		flowLayout.setAlignment(FlowLayout.LEFT);
		flowLayout.setVgap(2);
		flowLayout.setHgap(2);
		panel_1.add(panel, BorderLayout.SOUTH);

		JCheckBox chckbxNewCheckBox = new JCheckBox("New check box");
		panel.add(chckbxNewCheckBox);
		setLayout(new BorderLayout(0, 0));

		JPanel panel_2 = new JPanel();
		add(panel_2, BorderLayout.NORTH);

		JSplitPane splitPane = new JSplitPane();
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		add(splitPane, BorderLayout.CENTER);

		jPanelDetail = new JPanel();
		GridBagConstraints gbc_jPanelDetail = new GridBagConstraints();
		gbc_jPanelDetail.insets = new Insets(0, 0, 0, 5);
		gbc_jPanelDetail.fill = GridBagConstraints.BOTH;
		gbc_jPanelDetail.gridx = 1;
		gbc_jPanelDetail.gridy = 4;
		splitPane.setBottomComponent(jPanelDetail);
		splitPane.setTopComponent(panel_1);
		jPanelDetail.setLayout(new BorderLayout(0, 0));

		reportDetails = new JTable();
		reportDetails.setPreferredScrollableViewportSize(new Dimension(0, 150));
		reportDetails.setFillsViewportHeight(true);
		reportDetails.setAutoCreateRowSorter(true);
		JScrollPane scrollPane_1 = new JScrollPane(reportDetails);
		jPanelDetail.add(scrollPane_1, BorderLayout.CENTER);

		JScrollPane scrollPane = new JScrollPane(reportList);
		panel_1.add(scrollPane, BorderLayout.CENTER);

		// scrollPane_1.setViewportView(reportDetails);
		if (repository.getRecordings(ReportRecording.class,true).size() > 0 && model.getRowCount()>0) {
			// recEditor = getEditor(repository.getRecording(0));
			// jPanelDetail.add(recEditor, BorderLayout.CENTER);
				reportList.setRowSelectionInterval(0, 0);
		}
		jPanelDetail.revalidate();
	}

	private void initColumnSizes(JTable theTable) {
		MyTableModel2 model = (MyTableModel2) theTable.getModel();
		TableColumn column = null;
		Component comp = null;
		int headerWidth = 0;
		int cellWidth = 0;
		// Object[] longValues = model.longValues;
		TableCellRenderer headerRenderer = theTable.getTableHeader().getDefaultRenderer();

		for (int i = 0; i < 4; i++) {
			column = theTable.getColumnModel().getColumn(i);
			comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
			headerWidth = comp.getPreferredSize().width;
			cellWidth = comp.getPreferredSize().width;
			column.setPreferredWidth(Math.max(headerWidth, cellWidth));
		}
	}

	public class MyTableModel2 extends AbstractTableModel {
		private String[] header;
		private Vector data = new Vector();
		private MineResultSet mineResultSet1;

		public MyTableModel2(Vector<Object[]> data, String[] header,MineResultSet _mineResultSet1) {
			this.header = header;
			this.data = data;
			mineResultSet1=_mineResultSet1;
		}

		@Override
		public int getColumnCount() {
			if (header == null) {
				return 0;
			} else
				return header.length;
		}

		@Override
		public String getColumnName(int column) {
			return header[column];
		}

		@Override
		public int getRowCount() {
			 return repository.getReportRecordings(mineResultSet1, true).size();
			//return repository.getRecordings(ReportRecording.class,true).size();
		}

		public void addRow(Object[] obj) {
			data.add(obj);
		}

		public void updateRow(int rowId, Object[] obj) {
			data.set(rowId, obj);
		}

		@Override
		public Object getValueAt(int row, int column) {
			if (column == 0) {
				//return repository.getRecording(ReportRecording.class, row,true).getName();
				return ((ArrayList<Recording>)repository.getReportRecordings(mineResultSet1, true)).get(row).getName();
			} else if (column == 1) {
				return (((ArrayList<Recording>) repository.getReportRecordings(mineResultSet1, true)).get(row).getRegexp());
			} else if (column == 2) {
				return (((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(row).getSubType());
			} else if (column == 3) {
				int rows=0;
				if (mineResultSet.getOccurenceReport() != null) {
					Iterator sourcesIterator=repository.getSources().iterator();
					while (sourcesIterator.hasNext())
					{
						Source src=(Source) sourcesIterator.next();
						if (src.getActive()  && mineResultSet.getOccurenceReport().containsKey(src)){
							if (mineResultSet.getOccurenceReport().get(src).containsKey(((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(row))){
							rows=rows+mineResultSet.getOccurenceReport().get(src).get(((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(row)).size();
							}
						}}
				}
				if (mineResultSet.getTop100Report() != null) {
						Iterator sourcesIterator=repository.getSources().iterator();
						while (sourcesIterator.hasNext())
						{
							Source src=(Source) sourcesIterator.next();
							if (src.getActive()  && mineResultSet.getTop100Report().containsKey(src)){
								if (mineResultSet.getTop100Report().get(src).containsKey(((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(row))){
								rows=rows+mineResultSet.getTop100Report().get(src).get(((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(row)).size();
								}
							}}
				}
				if (mineResultSet.getSumReport() != null) {
					Iterator sourcesIterator=repository.getSources().iterator();
					while (sourcesIterator.hasNext())
					{
						Source src=(Source) sourcesIterator.next();
						if (src.getActive()  && mineResultSet.getSumReport().containsKey(src)){
							if (mineResultSet.getSumReport().get(src).containsKey(((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(row))){
							rows=rows+mineResultSet.getSumReport().get(src).get(((ArrayList<ReportRecording>) repository.getReportRecordings(mineResultSet1, true)).get(row)).size();
							}
						}}
			}
					return (int) rows;
			} else if (column > 3 && column < 9) {
				stats = DataVault.getRecordingStats(((ArrayList<Recording>)repository.getReportRecordings(mineResultSet1, true)).get(row).getName());
				if (stats != null) {
					if (Preferences.getPreference("timings").equals("false") && Preferences.getPreference("matches").equals("true") ) {
						return stats[column - 2];
					} else {
						return stats[column - 4];
						} 
				} else
					return 0;
			} else
				return 0;

		}

		@Override
		public void setValueAt(Object value, int row, int column) {

			if (column == 3) {
				logger.info("setValueAt calls setActiveRecording");
				// .toggleActiveRecording(repository.getRecording(MetadataRecording.class,
				// row));
				fireTableCellUpdated(row, column);
				// logger.info("control of setValueAt: "+source.isActiveRecordingOnSource(repository.getRecording(MetadataRecording.class,
				// row)));
			} else {
				((Object[]) data.get(row))[column] = value;
				// logger.info("setValueAt"+row+","+column);
				fireTableCellUpdated(row, column);
			}
		}

		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			// Note that the data/cell address is constant,
			// no matter where the cell appears onscreen.
				return false;
		}
	}

	/**
	 * Create the GUI and show it. For thread safety, this method should be
	 * invoked from the event-dispatching thread.
	 * 
	 * private static void createAndShowGUI() { // Create and set up the window.
	 * JFrame frame = new JFrame("RecordingEditorTable");
	 * frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	 * 
	 * // Create and set up the content pane. ReportPanel newContentPane = new
	 * ReportPanel(null, repository); newContentPane.setOpaque(true); // content
	 * panes must be opaque frame.setContentPane(newContentPane);
	 * 
	 * // Display the window. frame.pack(); frame.setVisible(true); }
	 */

	/*
	 * public ArrayList<RecordingItem> getRecordingItems() {
	 * ArrayList<RecordingItem> toReturn = new ArrayList<RecordingItem>(); for
	 * (int i = 0; i < data.size(); i++) { // model.getRowCount()
	 * toReturn.add(new RecordingItem((String) model.getValueAt(i, 0),(String)
	 * model.getValueAt(i, 1), (String) model.getValueAt(i, 2), (Boolean)
	 * model.getValueAt(i, 3)); } return toReturn; }
	 */

	/*
	 * public void Add() { data.add(new Object[] { " ", "", "long", "",
	 * Boolean.TRUE, "" }); table.repaint(); }
	 */

	public void Remove() {
		data.remove(((reportList.getSelectedRow() != -1) ? reportList.convertRowIndexToModel(reportList.getSelectedRow()) : -1));
		repository.deleteRecording(((reportList.getSelectedRow() != -1) ? reportList.convertRowIndexToModel(reportList.getSelectedRow()) : -1));
		reportList.repaint();
	}

	public class RecordReportTableModel extends AbstractTableModel {
		private ArrayList<Object[]> header;
		private ArrayList<List<Object>> data;

		public RecordReportTableModel(ArrayList<List<Object>> data1, ArrayList<Object[]> rIArrayList) {
			this.header = rIArrayList;
			this.data = data1;
		}

		@Override
		public int getColumnCount() {
			if (header == null) {
				return 0;
			} else
				return header.size();
		}

		@Override
		public String getColumnName(int column) {
			return (String) header.get(column)[0];
		}

		@Override
		public int getRowCount() {
			return data.size();

		}

		public void addRow(List<Object> obj) {
			data.add(obj);
		}

		public void updateRow(int rowId, List<Object> obj) {
			data.set(rowId, obj);
		}

		@Override
		public Object getValueAt(int row, int column) {
			if (column <= (data.get(row).size())) {
				// logger.info("row: " + row + ", column "+column +",header.get(column "+header.get(column) );
				 //" ,col: "+column + "data: "
				 //+data.get(row).get(column));
				return ((Class) header.get(column)[1]).cast(data.get(row).get(column));
			} else if (column == (data.get(row).size())) {

			}
			return ((Class) header.get(column)[1]).cast((Double) 0.0);

		}

		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			return (Class) header.get(c)[1];
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			return false;
		}

	}

}
 public class ReportRecordingSelectorPanel extends JPanel {
	private static Logger logger = Logger.getLogger(ReportRecordingSelectorPanel.class.getName());
	public static JTable table;
	JPanel jPanelDetail;
	ReportRecordingSelectorPanel thiis = this;
	boolean DEBUG = false;;
	static Matcher m;
	static ArrayList records = null;
	private String[] header = { "name", "regexp", "type","subtype", "active" };
	private Vector<Object[]> data = new Vector<Object[]>();
	private Repository repository = null;
	private JPanel recEditor = null;
	public logdruid.ui.mainpanel.ReportRecordingSelectorPanel.MyTableModel model;
	private Source source;

	/**
	 * Create the panel.
	 */
	public ReportRecordingSelectorPanel(final Repository rep, Source src) {
		repository = rep;
		source = src;
		records = rep.getRecordings(ReportRecording.class,true);
		// Collections.sort(records);
		Iterator it = records.iterator();
		while (it.hasNext()) {
			Recording record = (Recording) it.next();
			logger.debug(record.getName());
			logger.debug(record.getRegexp());
			logger.debug(record.getType());
			logger.debug(src.getSourceName());
			logger.debug(src.isActiveRecordingOnSource(record));
				data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), src.isActiveRecordingOnSource(record),((ReportRecording)record).getSubType() });
			}
		
		model = new logdruid.ui.mainpanel.ReportRecordingSelectorPanel.MyTableModel(data, header);
		logger.debug("source is " + ((source == null) ? "null" : src.getSourceName()));
		JPanel panel_1 = new JPanel();
		GridBagConstraints gbc_panel_1 = new GridBagConstraints();
		gbc_panel_1.fill = GridBagConstraints.BOTH;
		gbc_panel_1.insets = new Insets(5, 0, 5, 5);
		gbc_panel_1.gridx = 1;
		gbc_panel_1.gridy = 0;
		panel_1.setLayout(new BorderLayout(0, 0));

		table = new JTable(model);
		JScrollPane scrollPane = new JScrollPane(table);
		panel_1.add(scrollPane, BorderLayout.CENTER);

		table.setPreferredScrollableViewportSize(new Dimension(0, 150));
		table.setFillsViewportHeight(true);
		table.setAutoCreateRowSorter(true);

		// Set up column sizes.
		initColumnSizes(table);

		setLayout(new BorderLayout(0, 0));

		JSplitPane splitPane = new JSplitPane();
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		add(splitPane);
		jPanelDetail = new JPanel();
		splitPane.setBottomComponent(jPanelDetail);
		splitPane.setTopComponent(panel_1);

		GridBagConstraints gbc_jPanelDetail = new GridBagConstraints();
		gbc_jPanelDetail.insets = new Insets(0, 0, 0, 5);
		gbc_jPanelDetail.fill = GridBagConstraints.BOTH;
		gbc_jPanelDetail.gridx = 1;
		gbc_jPanelDetail.gridy = 3;
		jPanelDetail.setLayout(new BorderLayout(0, 0));
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			public void valueChanged(ListSelectionEvent e) {
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
				logger.debug("ListSelectionListener - selectedRow: " + selectedRow);
				if (selectedRow >= 0) {
					if (jPanelDetail != null) {
						logger.debug("ListSelectionListener - valueChanged");
						jPanelDetail.removeAll();
						recEditor = getEditor(repository.getRecording(ReportRecording.class, selectedRow,true));
						if (recEditor != null) {
							jPanelDetail.add(recEditor, BorderLayout.CENTER);
						}
						jPanelDetail.revalidate();
					}
				}
			}
		});
		if (repository.getRecordings(ReportRecording.class,true).size() > 0) {
			recEditor = getEditor(repository.getRecording(ReportRecording.class, 0,true));
			jPanelDetail.add(recEditor, BorderLayout.CENTER);
			table.setRowSelectionInterval(0, 0);
		}
		if (model.getRowCount()>0){
			table.getRowSorter().toggleSortOrder(0);
			table.setRowSelectionInterval(0, 0);
		}
	}

	private JPanel getEditor(Recording rec) {
			return new ReportRecordingEditor(this,repository, rec.getExampleLine(), rec.getRegexp(), ((ReportRecording) rec),((ReportRecording)rec).getSubType());
	}
/*
	public void reloadTable() {
		int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
		records = repository.getRecordings(ReportRecording.class);
		logger.debug("reloadTable - nb records : " + records.size());
		Iterator it = records.iterator();
		int count = 0;
		data.clear();
		// this.repaint();

		logger.debug("reloadTable - 1");
		while (it.hasNext()) {
			Boolean bool = false;
			Recording record = (Recording) it.next();
			if (source != null) {
				bool = source.isActiveRecordingOnSource(record);
				logger.debug("ReloadTable with " + record.getName() + " with isActiveRecordingOnSource: " + source.isActiveRecordingOnSource(record));
			}
			data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), bool });
			logger.debug("name: " + record.getName() + "regexp: " + record.getRegexp() + "isActive: " + record.getIsActive());
		}
		// model.fireTableDataChanged();
		logger.debug("reloadTable - 2");
		// this.repaint();
		table.repaint();

		logger.debug("reloadTable - 3");
		this.revalidate();

	}
*/
	private void initColumnSizes(JTable theTable) {
		TableColumn column = null;
		Component comp = null;
		int headerWidth = 0;
		int cellWidth = 0;
		TableCellRenderer headerRenderer = theTable.getTableHeader().getDefaultRenderer();

		for (int i = 0; i < 4; i++) {
			column = theTable.getColumnModel().getColumn(i);
			comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
			headerWidth = comp.getPreferredSize().width;
			cellWidth = comp.getPreferredSize().width;
			column.setPreferredWidth(Math.max(headerWidth, cellWidth));
		}
	}
	
	public void Remove() {
		data.remove(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		repository.deleteRecording(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		table.repaint();
	}

	public class MyTableModel extends AbstractTableModel {
		private String[] header;
		private Vector<Object[]> data;

		public MyTableModel(Vector<Object[]> data2, String[] header) {
			this.header = header;
			this.data = data2;
		}

		@Override
		public int getColumnCount() {
			if (header == null) {
				return 0;
			} else
				return header.length;
		}

		@Override
		public String getColumnName(int column) {
			return header[column];
		}

		@Override
		public int getRowCount() {
			return repository.getRecordings(ReportRecording.class,true).size();
		}

		@Override
		public Object getValueAt(int row, int column) {
			if (column == 0 ) {
				return repository.getRecording(ReportRecording.class,row,true).getName();
			} else if (column == 1 ) {
				return repository.getRecording(ReportRecording.class,row,true).getRegexp();
			} else if (column == 2 ) {
				return repository.getRecording(ReportRecording.class,row,true).getType();
			} else if (column == 3 ) {
				return ((ReportRecording)repository.getRecording(ReportRecording.class,row,true)).getSubType();
			} else if (column == 4 ) {
			logger.debug("getvalueat name" + ((ReportRecording) repository.getRecording(ReportRecording.class, row,true)).getName());
			logger.debug("getvalueat is active" + source.isActiveRecordingOnSource(repository.getRecording(ReportRecording.class, row,true)));
			return source.isActiveRecordingOnSource(repository.getRecording(ReportRecording.class, row,true));
		}
			else return 0;
		}

		public void addRow(Object[] obj) {
			data.add(obj);
			//table.repaint();
		}

		public void updateRow(int rowId, Object[] obj) {
			data.set(rowId, obj);
			//table.repaint();
		}

		@Override
		public void setValueAt(Object value, int row, int column) {
			if (column == 4 && source != null) {
				logger.debug("setValueAt calls setActiveRecording");
				source.toggleActiveRecording(repository.getRecording(ReportRecording.class, row,true));
				fireTableCellUpdated(row, column);
				// logger.debug("control of setValueAt: "+source.isActiveRecordingOnSource(repository.getRecording(MetadataRecording.class,
				// row)));
			} else {
				((Object[]) data.get(row))[column] = value;
					fireTableCellUpdated(row, column);
			}
			table.repaint();
		}

		/*
		 * @Override public void setValueAt(Object value, int row, int column) {
		 * data.get(row)[column] = value; fireTableCellUpdated(row, column); }
		 */
		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			// Note that the data/cell address is constant,
			// no matt&er where the cell appears onscreen.
			if (col > 2) {
				return true;
			} else {
				return false;
			}
		}
	}


	public void Add() {
		data.add(new Object[] { "", ".*", "long", Boolean.FALSE });
		table.repaint();
	}
}
 public class SourceInfoPanel extends JPanel {
	private static Logger logger = Logger.getLogger(SourceInfoPanel.class.getName());
	private Document groupDoc;
	private Document filesDoc;

	/**
	 * Create the panel.
	 */
	public SourceInfoPanel(Repository repo, Source src) {
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[]{10, 665, 5, 0};
		gridBagLayout.rowHeights = new int[]{232, 257, 10, 0};
		gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
		gridBagLayout.rowWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
		setLayout(gridBagLayout);
		
				JPanel panel_7 = new JPanel();
				GridBagConstraints gbc_panel_7 = new GridBagConstraints();
				gbc_panel_7.anchor = GridBagConstraints.NORTH;
				gbc_panel_7.fill = GridBagConstraints.HORIZONTAL;
				gbc_panel_7.insets = new Insets(0, 0, 5, 5);
				gbc_panel_7.gridx = 1;
				gbc_panel_7.gridy = 0;
				add(panel_7, gbc_panel_7);
										GridBagLayout gbl_panel_7 = new GridBagLayout();
										gbl_panel_7.columnWidths = new int[]{207, 19, 0};
										gbl_panel_7.rowHeights = new int[]{10, 230, 0};
										gbl_panel_7.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
										gbl_panel_7.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
										panel_7.setLayout(gbl_panel_7);
												
														JPanel panel_2 = new JPanel();
														GridBagConstraints gbc_panel_2 = new GridBagConstraints();
														gbc_panel_2.fill = GridBagConstraints.VERTICAL;
														gbc_panel_2.anchor = GridBagConstraints.WEST;
														gbc_panel_2.insets = new Insets(0, 0, 0, 5);
														gbc_panel_2.gridx = 0;
														gbc_panel_2.gridy = 1;
														panel_7.add(panel_2, gbc_panel_2);
														GridBagLayout gbl_panel_2 = new GridBagLayout();
														gbl_panel_2.columnWidths = new int[] { 10, 142, 0, 0 };
														gbl_panel_2.rowHeights = new int[] { 0, -63, 0, 0, 0, 0, 0, 0 };
														gbl_panel_2.columnWeights = new double[] { 0.0, 1.0, 0.0, Double.MIN_VALUE };
														gbl_panel_2.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE };
														panel_2.setLayout(gbl_panel_2);
														
																JPanel panel_3 = new JPanel();
																FlowLayout flowLayout = (FlowLayout) panel_3.getLayout();
																flowLayout.setAlignment(FlowLayout.LEFT);
																GridBagConstraints gbc_panel_3 = new GridBagConstraints();
																gbc_panel_3.anchor = GridBagConstraints.NORTHWEST;
																gbc_panel_3.insets = new Insets(0, 0, 5, 5);
																gbc_panel_3.gridx = 1;
																gbc_panel_3.gridy = 1;
																panel_2.add(panel_3, gbc_panel_3);
																
																		JLabel nameLabel = new JLabel("Name :");
																		panel_3.add(nameLabel);
																		
																				JLabel nameValueLabel = new JLabel(src.getSourceName());
																				panel_3.add(nameValueLabel);
																						
																						JPanel panel_1 = new JPanel();
																						GridBagConstraints gbc_panel_1 = new GridBagConstraints();
																						gbc_panel_1.anchor = GridBagConstraints.WEST;
																						gbc_panel_1.insets = new Insets(0, 0, 5, 5);
																						gbc_panel_1.fill = GridBagConstraints.VERTICAL;
																						gbc_panel_1.gridx = 1;
																						gbc_panel_1.gridy = 2;
																						panel_2.add(panel_1, gbc_panel_1);
																						
																						JLabel lblNumberOfGroups = new JLabel("Number of groups :");
																						panel_1.add(lblNumberOfGroups);
																						
																						JLabel nbGroupsValueLabel = new JLabel();
																						panel_1.add(nbGroupsValueLabel);
																				
																						JPanel panel_5 = new JPanel();
																						FlowLayout flowLayout_3 = (FlowLayout) panel_5.getLayout();
																						flowLayout_3.setAlignment(FlowLayout.LEFT);
																						GridBagConstraints gbc_panel_5 = new GridBagConstraints();
																						gbc_panel_5.insets = new Insets(0, 0, 5, 5);
																						gbc_panel_5.anchor = GridBagConstraints.WEST;
																						gbc_panel_5.gridx = 1;
																						gbc_panel_5.gridy = 3;
																						panel_2.add(panel_5, gbc_panel_5);
																						
																								JLabel nbFilesLabel = new JLabel("Number of files :");
																								panel_5.add(nbFilesLabel);
																								
																										JLabel nbFilesValueLabel = new JLabel();
																										panel_5.add(nbFilesValueLabel);
																										
																										JPanel panel_8 = new JPanel();
																										FlowLayout flowLayout_2 = (FlowLayout) panel_8.getLayout();
																										flowLayout_2.setAlignment(FlowLayout.LEFT);
																										GridBagConstraints gbc_panel_8 = new GridBagConstraints();
																										gbc_panel_8.anchor = GridBagConstraints.NORTH;
																										gbc_panel_8.insets = new Insets(0, 0, 5, 5);
																										gbc_panel_8.fill = GridBagConstraints.HORIZONTAL;
																										gbc_panel_8.gridx = 1;
																										gbc_panel_8.gridy = 4;
																										panel_2.add(panel_8, gbc_panel_8);
																										
																										JLabel lblSizeOfFiles = new JLabel("Size of files :");
																										panel_8.add(lblSizeOfFiles);
																										
																										JLabel filesSize = new JLabel();
																										panel_8.add(filesSize);
																										
																												JPanel panel_4 = new JPanel();
																												FlowLayout flowLayout_1 = (FlowLayout) panel_4.getLayout();
																												flowLayout_1.setAlignment(FlowLayout.LEFT);
																												GridBagConstraints gbc_panel_4 = new GridBagConstraints();
																												gbc_panel_4.anchor = GridBagConstraints.NORTH;
																												gbc_panel_4.insets = new Insets(0, 0, 5, 5);
																												gbc_panel_4.gridx = 1;
																												gbc_panel_4.gridy = 5;
																												panel_2.add(panel_4, gbc_panel_4);
										
												JPanel panel_6 = new JPanel();
												GridBagConstraints gbc_panel_6 = new GridBagConstraints();
												gbc_panel_6.fill = GridBagConstraints.BOTH;
												gbc_panel_6.gridx = 1;
												gbc_panel_6.gridy = 1;
												panel_7.add(panel_6, gbc_panel_6);
												panel_6.setBorder(new TitledBorder(null, "Groups", TitledBorder.LEADING, TitledBorder.TOP, null, null));
												panel_6.setLayout(new BorderLayout(0, 0));
												
														JTextPane textPane_1 = new JTextPane();
														textPane_1.setEditable(false);
														textPane_1.setFont(new Font("Dialog", Font.PLAIN, 11));
														// panel_6.add(textPane_1, BorderLayout.SOUTH);

														JScrollPane scrollPane_1 = new JScrollPane(textPane_1);
														panel_6.add(scrollPane_1, BorderLayout.CENTER);
														groupDoc = textPane_1.getDocument();
		
				JPanel panel = new JPanel();
				panel.setBorder(new TitledBorder(null, "Files", TitledBorder.LEADING, TitledBorder.TOP, null, null));
				GridBagConstraints gbc_panel = new GridBagConstraints();
				gbc_panel.insets = new Insets(0, 0, 5, 5);
				gbc_panel.fill = GridBagConstraints.BOTH;
				gbc_panel.gridx = 1;
				gbc_panel.gridy = 1;
				add(panel, gbc_panel);
				panel.setLayout(new BorderLayout(0, 0));
				JTextPane textPane = new JTextPane();
				textPane.setEditable(false);
				textPane.setFont(new Font("Dialog", Font.PLAIN, 11));
				JScrollPane scrollPane = new JScrollPane(textPane);
				panel.add(scrollPane);
		Highlighter h = textPane.getHighlighter();
		if (repo != null && repo.getBaseSourcePath() != null) {
			ChartData cd = DataMiner.gatherSourceData(repo,true);
			Map<String, ArrayList<FileRecord>> hm = cd.getGroupFilesMap(src);
			if (hm!=null){
			logger.debug("source: "+src.getSourceName()+",  map: "+hm+",  map size: "+ hm.size());
			filesDoc = textPane.getDocument();
			//Iterator it = hm.entrySet().iterator();
			ArrayList<String> groupArrayList = new ArrayList<String>(hm.keySet());
			Collections.sort(groupArrayList, new AlphanumComparator());
			Iterator it = groupArrayList.iterator();
			int nbFiles = 0;
			long size=0;
			while (it.hasNext()) {
				try {
					int currGroupIndex = groupDoc.getLength();
					int currFilesIndex = filesDoc.getLength();
					String sourcePairs = (String) it.next();
					final String groupString = (String) sourcePairs;
				//	logger.debug("groupString: "+groupString);
					ArrayList<String> filesString = new ArrayList<String>();
					ArrayList files = (ArrayList) hm.get(groupString);
					nbFiles += files.size();
					Iterator<FileRecord> iterator =files.iterator();
					while (iterator.hasNext())
						{
						FileRecord fr = iterator.next();
						size=size+((File)fr.getFile()).length();
						filesString.add("- "+ new File(repo.getBaseSourcePath()).toURI().relativize(new File((fr).getCompletePath()).toURI()).getPath()+ "\n");
				//		logger.debug(fr.getFile().getName()+" "+((File)fr.getFile()).length());
						}
					groupDoc.insertString(groupDoc.getLength(), groupString + "(" + files.size() + " file"+(nbFiles>1?"s":"")+")\n", null);
					filesDoc.insertString(filesDoc.getLength(), groupString + "\n", null);

					SimpleAttributeSet sas = new SimpleAttributeSet(); 
					StyleConstants.setBold(sas, true);
					textPane.getStyledDocument().setCharacterAttributes(currFilesIndex , groupString.length()-1, sas, false);
					textPane_1.getStyledDocument().setCharacterAttributes(currGroupIndex , groupString.length()-1, sas, false);
					
					//h.addHighlight(currIndex , currIndex + groupString.length()-1,  DefaultHighlighter.DefaultPainter);
				/*	Iterator vecIt = files.iterator();
					while (vecIt.hasNext()) {
						filesDoc.insertString(filesDoc.getLength(),"- "+ new File(repo.getBaseSourcePath()).toURI().relativize(new File(((FileRecord)vecIt.next()).getCompletePath()).toURI()).getPath()+ "\n", null);
						
					}*/
				//	removing sorting now that sorting based on date in files
				// Collections.sort(filesString, new AlphanumComparator());
					Iterator vecIt = filesString.iterator();
					while (vecIt.hasNext()) {
						filesDoc.insertString(filesDoc.getLength(),(String)vecIt.next(), null);
						
					}
				} catch (BadLocationException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			textPane.setCaretPosition(0);
			textPane_1.setCaretPosition(0);
			nbGroupsValueLabel.setText(""+hm.keySet().size());
			nbFilesValueLabel.setText("" + nbFiles);
			filesSize.setText(""+size/1024000+"MB");
		}}

	}
} public class SourcePanel extends JPanel {
	private static Logger logger = Logger.getLogger(SourcePanel.class.getName());
	private JTextField basePathTextField;
	boolean DEBUG = false;
	private JTable table;
	private String[] header = { "name", "regexp", "Date Format", "active", "nb files", "size(MB)" };
	private Repository repository;
	private ArrayList<Object[]> data = new ArrayList<Object[]>();
	public MyTableModel2 model;
	static ArrayList<Source> sourceArrayList = null;
	private JTextPane txtpnTest = null;
	private Document doc;
	private MainFrame mainFrame;
	JCheckBox chckbxSubfolders = null;
	JCheckBox chckbxOnlyMatches = null;
	Map<Source, long[]> srcFileSummary = new HashMap<Source, long[]>();

	/**
	 * Create the panel.
	 */
	public SourcePanel(final Repository repo, final MainFrame _mainFrame) {
		mainFrame = _mainFrame;
		model = new MyTableModel2(data, header);
		repository = repo;
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[] { 575, 0 };
		gridBagLayout.rowHeights = new int[] { 45, 338, 0 };
		gridBagLayout.columnWeights = new double[] { 1.0, Double.MIN_VALUE };
		gridBagLayout.rowWeights = new double[] { 0.0, 1.0, Double.MIN_VALUE };
		setLayout(gridBagLayout);

		JPanel descriptionPanel = new JPanel();
		GridBagConstraints gbc_descriptionPanel = new GridBagConstraints();
		gbc_descriptionPanel.insets = new Insets(0, 0, 5, 0);
		gbc_descriptionPanel.fill = GridBagConstraints.BOTH;
		gbc_descriptionPanel.gridx = 0;
		gbc_descriptionPanel.gridy = 0;
		add(descriptionPanel, gbc_descriptionPanel);
		descriptionPanel.setLayout(new BorderLayout(0, 0));

		JPanel panel = new JPanel();
		descriptionPanel.add(panel, BorderLayout.EAST);

		JButton btnFolder = new JButton("Folder...");
		panel.add(btnFolder);

		JPanel panel_2 = new JPanel();
		descriptionPanel.add(panel_2, BorderLayout.CENTER);
		GridBagLayout gbl_panel_2 = new GridBagLayout();
		gbl_panel_2.columnWidths = new int[] { 499 };
		gbl_panel_2.rowHeights = new int[] { 2, 0, 0, 0 };
		gbl_panel_2.columnWeights = new double[] { 1.0 };
		gbl_panel_2.rowWeights = new double[] { 1.0, 0.0, 1.0, 1.0 };
		panel_2.setLayout(gbl_panel_2);

		JPanel panel_5 = new JPanel();
		FlowLayout flowLayout = (FlowLayout) panel_5.getLayout();
		flowLayout.setVgap(2);
		flowLayout.setHgap(2);
		GridBagConstraints gbc_panel_5 = new GridBagConstraints();
		gbc_panel_5.insets = new Insets(0, 0, 5, 0);
		gbc_panel_5.fill = GridBagConstraints.BOTH;
		gbc_panel_5.gridx = 0;
		gbc_panel_5.gridy = 0;
		panel_2.add(panel_5, gbc_panel_5);

		basePathTextField = new JTextField();
		basePathTextField.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				File temp = new File(basePathTextField.getText());
				if (temp.exists()) {
					repo.setBaseSourcePath(basePathTextField.getText());
					_mainFrame.setTitle("LogDruid - " + _mainFrame.configFile + " - " + basePathTextField.getText());
					// _mainFrame.setTitle("LogDruid - " +
					// _mainFrame.currentRepositoryFile + " - " +
					// basePathTextField.getText());
				}
			}
		});
		GridBagConstraints gbc_textField = new GridBagConstraints();
		gbc_textField.insets = new Insets(0, 0, 5, 0);
		gbc_textField.fill = GridBagConstraints.HORIZONTAL;
		gbc_textField.gridx = 0;
		gbc_textField.gridy = 1;
		panel_2.add(basePathTextField, gbc_textField);
		basePathTextField.setColumns(60);
		basePathTextField.setText(repo.getBaseSourcePath());

		JPanel panel_4 = new JPanel();
		FlowLayout flowLayout_1 = (FlowLayout) panel_4.getLayout();
		flowLayout_1.setHgap(2);
		flowLayout_1.setVgap(2);
		GridBagConstraints gbc_panel_4 = new GridBagConstraints();
		gbc_panel_4.insets = new Insets(0, 0, 5, 0);
		gbc_panel_4.fill = GridBagConstraints.BOTH;
		gbc_panel_4.gridx = 0;
		gbc_panel_4.gridy = 2;
		panel_2.add(panel_4, gbc_panel_4);

		JPanel panel_3 = new JPanel();
		FlowLayout flowLayout_2 = (FlowLayout) panel_3.getLayout();
		flowLayout_2.setVgap(10);
		descriptionPanel.add(panel_3, BorderLayout.WEST);

		JLabel lblBasePath = new JLabel("Logs folder:");
		panel_3.add(lblBasePath);
		btnFolder.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				FileChooserDialog fileChooserDialog;
				File temp = new File(basePathTextField.getText());
				if (temp.exists()) {
					fileChooserDialog = new FileChooserDialog(temp);
				} else {
					fileChooserDialog = new FileChooserDialog();
				}
				if ((fileChooserDialog != null) && (fileChooserDialog.isValidate())) {

					for (File file : fileChooserDialog.getSelectedFiles()) {
						repository.setBaseSourcePath(file.getAbsolutePath());
						basePathTextField.setText(file.getAbsolutePath());
						repo.setBaseSourcePath(file.getAbsolutePath());
						_mainFrame.setTitle("LogDruid - " + _mainFrame.configFile + " - " + basePathTextField.getText());
					}
				}
			}
		});

		JPanel tablePanel = new JPanel();
		GridBagConstraints gbc_tablePanel = new GridBagConstraints();
		gbc_tablePanel.fill = GridBagConstraints.BOTH;
		gbc_tablePanel.gridx = 0;
		gbc_tablePanel.gridy = 1;
		add(tablePanel, gbc_tablePanel);
		tablePanel.setLayout(new BorderLayout(0, 0));

		JSplitPane splitPane = new JSplitPane();
		splitPane.setOneTouchExpandable(true);
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		tablePanel.add(splitPane, BorderLayout.CENTER);

		JPanel fileMatchPanel = new JPanel();
		splitPane.setRightComponent(fileMatchPanel);
		fileMatchPanel.setLayout(new BorderLayout(0, 0));
		JPanel panel_1 = new JPanel();
		fileMatchPanel.add(panel_1, BorderLayout.CENTER);
		panel_1.setLayout(new BorderLayout(0, 0));
		txtpnTest = new JTextPane();

		JScrollPane scrollPane = new JScrollPane(txtpnTest);
		panel_1.add(scrollPane);

		JPanel panel_6 = new JPanel();
		panel_6.setMinimumSize(new Dimension(0, 200));
		panel_6.setPreferredSize(new Dimension(0, 300));
		splitPane.setLeftComponent(panel_6);
		panel_6.setLayout(new BorderLayout(0, 0));

		JPanel buttonsPanel = new JPanel();
		panel_6.add(buttonsPanel, BorderLayout.SOUTH);

		JButton btnNew = new JButton("New");
		buttonsPanel.add(btnNew);

		JButton btnDelete = new JButton("Delete");
		btnDelete.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
				repository.deleteSource(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
			//	reloadTable();
				if (selectedRow == table.getRowCount()) {
					table.setRowSelectionInterval(selectedRow - 1, selectedRow - 1);
				} else if (selectedRow > 0) {
					table.setRowSelectionInterval(selectedRow, selectedRow);
				} else {
					table.setRowSelectionInterval(0, 0);
				}
				mainFrame.updateTreeSources(repository.getSources());
				refreshList();
				logger.info("selectedRow: " + selectedRow + " row count: " + table.getRowCount());

			}
		});
		buttonsPanel.add(btnDelete);

		JSeparator separator = new JSeparator();
		separator.setOrientation(SwingConstants.VERTICAL);
		buttonsPanel.add(separator);
		JButton btnRefresh = new JButton("Refresh");
		btnRefresh.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
			//	updateSources();
			//	reloadTable();
				if (selectedRow > 0) {
					table.setRowSelectionInterval(selectedRow, selectedRow);
				}
				mainFrame.updateTreeSources(repository.getSources());
				refreshList();
			//	model.fireTableDataChanged();

			}
		});

		chckbxSubfolders = new JCheckBox("sub-folders");
		chckbxSubfolders.setFont(new Font("Dialog", Font.BOLD, 11));
		chckbxSubfolders.setSelected(repo.isRecursiveMode());
		chckbxSubfolders.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				repo.setRecursiveMode(chckbxSubfolders.isSelected());
			}
		});
		buttonsPanel.add(chckbxSubfolders);

		chckbxOnlyMatches = new JCheckBox("only matches");
		chckbxOnlyMatches.setFont(new Font("Dialog", Font.BOLD, 11));
		chckbxOnlyMatches.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				repo.setOnlyMatches(chckbxOnlyMatches.isSelected());
			}
		});
		buttonsPanel.add(chckbxOnlyMatches);
		chckbxOnlyMatches.setSelected(repo.isOnlyMatches());
		btnRefresh.setForeground(Color.BLUE);
		buttonsPanel.add(btnRefresh);

		JSeparator separator_1 = new JSeparator();
		separator_1.setOrientation(SwingConstants.VERTICAL);
		buttonsPanel.add(separator_1);

		JButton btnCheck = new JButton("Get samplings");
		btnCheck.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				DataMiner.populateRecordingSamples(repo);
			}
		});
		buttonsPanel.add(btnCheck);

		// scrollPane.add(txtpnTest);

		btnNew.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int rowCount = table.getRowCount();
				if (rowCount==-1){rowCount=0;}
				//int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
				logger.info(repository);	
				logger.info(rowCount);
				model.addRow(new Object[] { "default", ".*", "none", Boolean.TRUE, 0, 0 });
				model.fireTableDataChanged();//(rowCount, rowCount);
				table.setRowSelectionInterval(rowCount, rowCount);

			//	 table.repaint();
			//	reloadTable();
/*				if (selectedRow >= 0) {
					table.setRowSelectionInterval(selectedRow, selectedRow);
				} else {
					table.setRowSelectionInterval(0, 0);
				}*/
			//	table.repaint();
				refreshList();
				mainFrame.updateTreeSources(repository.getSources());
			}
		});
		table = new JTable(model);
		initColumnSizes(table);
	//	setUpProcessingColumn(table,table.getColumnModel().getColumn(2));
		//table.setAutoCreateRowSorter(true);

	
		JScrollPane scrollPane_1 = new JScrollPane(table);
		panel_6.add(scrollPane_1);

		// tablePanel.add(table, BorderLayout.CENTER);
		table.getModel().addTableModelListener(new TableModelListener() {

			public void tableChanged(TableModelEvent e) {
				// if (!e.getValueIsAdjusting()){
				// model.fireTableDataChanged();
			//	int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
			//	updateSources();
				mainFrame.updateTreeSources(repository.getSources());
			//	reloadTable();
			//	table.setRowSelectionInterval(selectedRow, selectedRow);
				refreshList();
				// }
			}
		});

		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			public void valueChanged(ListSelectionEvent e) {
				if (!e.getValueIsAdjusting()) {
					// model.fireTableDataChanged();
		//			int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
		//			updateSources();
					mainFrame.updateTreeSources(repository.getSources());
			//		reloadTable();
			//		table.setRowSelectionInterval(selectedRow, selectedRow);
					refreshList();
				}
			}
		});
		
		table.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent me) {
				   if (table.getSelectedRow()!=-1){
					   int x = me.getX();
			            int y = me.getY();
			            int row = table.rowAtPoint(new Point(x,y));
			            int col = table.columnAtPoint(new Point(x,y));
			            if (col == 2)
			            {
					   DateSelector ds = new DateSelector(repository);
					   ds.setVisible(true);
					   if (ds.isValidate() && (ds.getDateFormat()!=null)){
						model.setValueAt(ds.getDateFormat(), table.getSelectedRow(), 2);
						model.fireTableCellUpdated(table.getSelectedRow(), 2);
						repository.getSource(row).setDateFormat((DateFormat)ds.getDateFormat());
						logger.debug("updated with " + ds.getDateFormat().getName() );   
						}
						
			            }}
			}
			});
			

	

		reloadTable();
		if (table.getRowCount() > 0) {
			table.setRowSelectionInterval(0, 0);
		}
		refreshList();
		
	/* if (model.getRowCount()>0){
			table.getRowSorter().toggleSortOrder(2);
			table.getRowSorter().toggleSortOrder(0);
			}*/
	}

	public void refreshList() {
		// ((table.getSelectedRow()!=-1)?table.convertRowIndexToModel(table.getSelectedRow()):-1)
		// persist repository
		// display selected row
		PatternCache patternCache = new PatternCache();
		Matcher matcher;
		List<File> listOfFiles = null;
		srcFileSummary = new HashMap<Source, long[]>();
		sourceArrayList = repository.getSources();
		if (((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1) >= 0 && repository.getBaseSourcePath() != null) {
			/*
			 * recEditor = new RecordingEditor(repository
			 * .getRecordings().get(((
			 * table.getSelectedRow()!=-1)?table.convertRowIndexToModel
			 * (table.getSelectedRow()):-1)), repository);
			 * jPanelDetail.removeAll();
			 */
			// jPanelDetail.add(recEditor, gbc_jPanelDetail);

			File folder = new File(repository.getBaseSourcePath());
			try {
				if (!folder.exists()) {
					if (logger.isEnabledFor(Level.INFO))
						logger.info("base path did, not exist defaulting to current: " + System.getProperty("user.dir"));
					folder = new File(System.getProperty("user.dir"));
					repository.setBaseSourcePath(System.getProperty("user.dir"));
					basePathTextField.setText(System.getProperty("user.dir"));
					repository.setRecursiveMode(false);
					chckbxSubfolders.setSelected(false);
				}
				if (repository.isRecursiveMode()) {
					long estimatedTime = 0;
					long startTime = System.currentTimeMillis();

					listOfFiles = FileListing.getFileListing(folder);
					estimatedTime = System.currentTimeMillis() - startTime;
					logger.debug("gathering time: " + estimatedTime);
				} else {
					listOfFiles = Arrays.asList(folder.listFiles());

				}
				// File[] listOfFiles = folder.listFiles();

			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			int[][] fileListMatches = new int[listOfFiles.size()][3];
			doc = txtpnTest.getDocument();
			try {
				doc.remove(0, doc.getLength());
			} catch (BadLocationException e2) {
				// TODO Auto-generated catch block
				e2.printStackTrace();
			}
			int count = 0;
			for (int i = 0; i < listOfFiles.size(); i++) {
				fileListMatches[i][0] = 0;
				if (listOfFiles.get(i).isFile()) {
					if (logger.isDebugEnabled())
						logger.debug("source File " + listOfFiles.get(i).getName());
					if (sourceArrayList != null) {
						Iterator<Source> it = sourceArrayList.iterator();
						count = 0;
						while (it.hasNext()) {
							Source src = (Source) it.next();

							String s1 = (src).getSourcePattern();
							matcher = patternCache.getPattern(s1,true).matcher(FileListing.getPath(repository, listOfFiles.get(i)));
							if (logger.isDebugEnabled())
								logger.debug("matching with pattern: " + s1);
							if (logger.isDebugEnabled())
								logger.debug("matching file: " + FileListing.getPath(repository, listOfFiles.get(i)));

							if (matcher.find()) {
								if (logger.isDebugEnabled())
									logger.debug("match" + FileListing.getPath(repository, listOfFiles.get(i)));
								if (count == ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1)) {
									if (src.getActive()) {
										fileListMatches[i][0] = 1;
									} else {
										fileListMatches[i][0] = 3;
									}
									fileListMatches[i][1] = matcher.start();
									fileListMatches[i][2] = matcher.end();
									if (logger.isDebugEnabled())
										logger.debug("matched file" + FileListing.getPath(repository, listOfFiles.get(i)));
								} else if (fileListMatches[i][0] == 0) {
									if (logger.isDebugEnabled())
										logger.debug("Already matched file" + FileListing.getPath(repository, listOfFiles.get(i)));
									if (src.getActive()) {
										fileListMatches[i][0] = 2;
									} else {
										fileListMatches[i][0] = 3;
									}

								}
								if (!srcFileSummary.containsKey(src)) {
									srcFileSummary.put(src, new long[] { 0, 0 });
								}
								long[] intTable = srcFileSummary.get(src);
								intTable[0] = intTable[0] + 1;
								intTable[1] = intTable[1] + listOfFiles.get(i).length();
								srcFileSummary.put(src, intTable);

								fileListMatches[i][1] = matcher.start();
								fileListMatches[i][2] = matcher.end();
							} else {
								// fileListMatches[i][0]=0;
								if (logger.isDebugEnabled())
									logger.debug("not matched file" + FileListing.getPath(repository, listOfFiles.get(i)));
							}

							count++;
						}
					}
				}
			}
			try {
				// txtpnTest.setText( "original text" );
				for (int i = 0; i < fileListMatches.length; i++) {
					int currIndex = doc.getLength();
					// String relative = new
					// File(repository.getBaseSourcePath()).toURI().relativize(new
					// File(listOfFiles.get(i).getCanonicalPath()+listOfFiles.get(i).getName()).toURI()).getPath();
					// logger.info("match added");
					Highlighter h = txtpnTest.getHighlighter();
					if (fileListMatches[i][0] == 1) {
						String fileName = FileListing.getPath(repository, listOfFiles.get(i));
						doc.insertString(doc.getLength(), fileName + "\n", null);
						txtpnTest.setCaretPosition(0);
						h.addHighlight(currIndex + fileListMatches[i][1], currIndex + fileListMatches[i][2], new DefaultHighlighter.DefaultHighlightPainter(
								Color.ORANGE));
						if (logger.isDebugEnabled())
							logger.debug("matched - l: " + i + "file" + FileListing.getPath(repository, listOfFiles.get(i)) + " currIndex : " + currIndex
									+ ", match start: " + fileListMatches[i][1] + ", match end: " + fileListMatches[i][2]);
					} else if (fileListMatches[i][0] == 2) {
						String fileName = FileListing.getPath(repository, listOfFiles.get(i));
						doc.insertString(doc.getLength(), fileName + "\n", null);
						txtpnTest.setCaretPosition(0);
						h.addHighlight(currIndex + fileListMatches[i][1], currIndex + fileListMatches[i][2], DefaultHighlighter.DefaultPainter);
						if (logger.isDebugEnabled())
							logger.debug("ALREADY matched - l: " + i + "file" + listOfFiles.get(i).getName() + " currIndex : " + currIndex + ", match start: "
									+ fileListMatches[i][1] + ", match end: " + fileListMatches[i][2]);

					} else if (fileListMatches[i][0] == 3) {
						String fileName = FileListing.getPath(repository, listOfFiles.get(i));
						doc.insertString(doc.getLength(), fileName + "\n", null);
						txtpnTest.setCaretPosition(0);
						h.addHighlight(currIndex + fileListMatches[i][1], currIndex + fileListMatches[i][2], new DefaultHighlighter.DefaultHighlightPainter(
								Color.lightGray));
						if (logger.isDebugEnabled())
							logger.debug("ALREADY matched - l: " + i + "file" + listOfFiles.get(i).getName() + " currIndex : " + currIndex + ", match start: "
									+ fileListMatches[i][1] + ", match end: " + fileListMatches[i][2]);

					} else if (!repository.isOnlyMatches()) {
						String fileName = FileListing.getPath(repository, listOfFiles.get(i));
						doc.insertString(doc.getLength(), fileName + "\n", null);
						txtpnTest.setCaretPosition(0);
					}
				}
				// txtpnTest.setText( "original text" );
			} catch (BadLocationException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		}
		sourceArrayList = repository.getSources();
		if (sourceArrayList != null) {
			Iterator<Source> it = sourceArrayList.iterator();
			int count = 0;
			data.clear();
			// this.repaint();
			while (it.hasNext()) {
				Source record = (Source) it.next();
				logger.debug("reloadTable - record reloaded : " + count + ", " + record + ", " + record.getSourcePattern() + ", " + record.getActive()
						+ " srcFileSummary.get(record): " + srcFileSummary.get(record));
				data.add(new Object[] { record.getSourceName(), record.getSourcePattern(), record.getDateFormat(),record.getActive(),
						srcFileSummary.get(record) != null ? srcFileSummary.get(record)[0] : 0,
						srcFileSummary.get(record) != null ? ((float) srcFileSummary.get(record)[1]) / 1024000 : 0 });
			}
			table.revalidate();
			table.repaint();
		}

	}

/*	public void updateSources() {
		// "name", "regexp", "active"
		Iterator it = data.iterator();
		Object[] obj;
		int count = 0;
		while (it.hasNext()) {
			obj = (Object[]) it.next();
			String stName = (String) obj[0];
			String stregexp = (String) obj[1];
			Boolean stActive = (Boolean) obj[2];
			// logger.info("stType: " +stType);
			// logger.info("getTypeString(stType) -: "
			// +Miner.getTypeString(stType) );
			// patternString += stBefore + "(" + Miner.getTypeString(stType) +
			// ")"+stAfter;
			Source source = repository.getSource(count);
			source.setSourceName(stName);
			source.setSourcePattern(stregexp);
			source.setActive(stActive);
			// repository.updateSource(count,stName,stregexp, stActive);
			logger.info("updateSources - Source updated : " + stName + ",regexp: " + stregexp);
			count++;
		}
	}*/

	public void reloadTable() {
		// int selectedRow = ((table.getSelectedRow() != -1) ?
		// table.convertRowIndexToModel(table.getSelectedRow()) : -1);
		sourceArrayList = repository.getSources();
		// Collections.sort(records);
		if (sourceArrayList != null) {
			Iterator<Source> it = sourceArrayList.iterator();
			int count = 0;
			data.clear();
			// this.repaint();
			while (it.hasNext()) {
				Source record = (Source) it.next();
				data.add(new Object[] { record.getSourceName(), record.getSourcePattern(), record.getActive(), 0, 0 });
				logger.debug("reloadTable - record reloaded : " + count + ", " + record + ", " + record.getSourcePattern() + ", " + record.getActive());
			}
			table.revalidate();
		}
	}

	private void initColumnSizes(JTable theTable) {
		// MyTableModel2 model = (MyTableModel2) theTable.getModel();
		TableColumn column = null;
		Component comp = null;
		int headerWidth = 0;
		int cellWidth = 0;
		TableCellRenderer headerRenderer = theTable.getTableHeader().getDefaultRenderer();

		for (int i = 0; i < 6; i++) {
			column = theTable.getColumnModel().getColumn(i);
			comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
			if (i < 3) {
				headerWidth = comp.getPreferredSize().width;
				cellWidth = comp.getPreferredSize().width;
				column.setPreferredWidth(400);
			} else {
				cellWidth = 140;
				column.setMaxWidth(cellWidth * 4);
				column.setPreferredWidth(cellWidth);
			}

		}	
	}

	class DateFormatRenderer extends JLabel implements TableCellRenderer {
		Border unselectedBorder = null;
		Border selectedBorder = null;
		boolean isBordered = true;

		public DateFormatRenderer(boolean isBordered) {
			this.isBordered = isBordered;
			setOpaque(true); // MUST do this for background to show up.
		}

		public Component getTableCellRendererComponent(JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column) {
			Color newColor = (Color) color;
			setBackground(newColor);
			if (isBordered) {
				if (isSelected) {
					if (selectedBorder == null) {
						selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getSelectionBackground());
					}
					setBorder(selectedBorder);
				} else {
					if (unselectedBorder == null) {
						unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getBackground());
					}
					setBorder(unselectedBorder);
				}
			}

			setToolTipText("RGB value: " + newColor.getRed() + ", " + newColor.getGreen() + ", " + newColor.getBlue());
			return this;
		}
	}

/*	public void setUpProcessingColumn(JTable theTable, TableColumn typeColumn) {
		JTextField textField= new JTextField();
		typeColumn.setCellEditor(new DefaultCellEditor(textField));
		DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
		renderer.setToolTipText("Click");
		typeColumn.setCellRenderer(renderer);
		  

		textField.addMouseListener(new java.awt.event.MouseAdapter(){

			public void mouseClicked(java.awt.event.MouseEvent e){
				//		JTextField combo = (JTextField) e.getSource();
			//	   Object selected = combo.get();
				   if (table.getSelectedRow()!=-1){
					   DateSelector ds = new DateSelector(repository);
					   if (ds.getDateFormat()!=null)
						model.setValueAt(ds.getDateFormat(), table.getSelectedRow(), 4);
						model.fireTableCellUpdated(table.getSelectedRow(), 4);
					}
				   }
				}
				);
	}
*/
	
	class MyTableModel2 extends AbstractTableModel {
		private String[] header;
		private ArrayList<Object[]> data;

		public MyTableModel2(ArrayList<Object[]> data, String[] header) {
			this.header = header;
			this.data = data;
		}

		@Override
		public int getColumnCount() {
			if (header == null) {
				return 0;
			} else
				return header.length;
		}

		@Override
		public String getColumnName(int column) {
			return header[column];
		}

		@Override
		public int getRowCount() {
			return data.size();
		}

		public void addRow(Object[] obj) {
			Source s = new Source("default", ".*", null, Boolean.TRUE);
			repository.addSource(s);
			data.add(obj);
		}

		public void updateRow(int rowId, Object[] obj) {
			data.set(rowId, obj);
		}

		@Override
		public Object getValueAt(int row, int column) {
			//return data.get(row)[column];
			if (column == 0 ) {
				return repository.getSource(row).getSourceName();
			} else if (column == 1 ) {
				return repository.getSource(row).getSourcePattern();
			} else if (column == 2 ) {
				if ( repository.getSource(row).getDateFormat()!=null)
				return ((String) repository.getSource(row).getDateFormat().getName() + " | "+ repository.getSource(row).getDateFormat().getDateFormat() );
				else {
					return "none";
				}
			} else if (column == 3 ) {
				return repository.getSource(row).getActive();
			} else if (column >= 4 ) {
				return data.get(row)[column];
			} 
			else return 0;
		}

		@Override
		public void setValueAt(Object value, int row, int column) {
			if (column == 0 ) {
				 repository.getSource(row).setSourceName((String) value);
					fireTableCellUpdated(row, column);
			} else if (column == 1 ) {
				repository.getSource(row).setSourcePattern((String) value);
				fireTableCellUpdated(row, column);
			} else if (column == 2 ) {
				repository.getSource(row).setDateFormat((DateFormat)value);
				logger.info("set "+((DateFormat)value).getPattern());
				fireTableCellUpdated(row, column);
			} else if (column == 3 ) {
				repository.getSource(row).setActive((Boolean)value);
				fireTableCellUpdated(row, column);
			} else {
				((Object[]) data.get(row))[column] = value;
					fireTableCellUpdated(row, column);
			}
		}

		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			if (c==2){
				return String.class;
			} else {
			return getValueAt(0, c).getClass();
			}
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			// Note that the data/cell address is constant,
			// no matt&er where the cell appears onscreen.
			if (col<4){
				return true;	
			} else return false;
		}
	}

	public void Remove() {
		data.remove(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		repository.deleteRecording(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		table.repaint();
	}
} public class StatRecordingSelectorPanel extends JPanel {
	private static Logger logger = Logger.getLogger(StatRecordingSelectorPanel.class.getName());
	public static JTable table;
	JPanel jPanelDetail;
	boolean DEBUG = false;
	static Matcher m;
	static ArrayList records = null;
	private String[] header = { "name", "regexp", "type", "active" };
	private ArrayList<Object[]> data = new ArrayList<Object[]>();
	private Repository repository = null;
	private JPanel recEditor = null;
	public logdruid.ui.mainpanel.StatRecordingSelectorPanel.MyTableModel model;
	private Source source;

	/**
	 * Create the panel.
	 */
	public StatRecordingSelectorPanel(final Repository rep, Source src) {
		repository = rep;
		source = src;
		records = rep.getRecordings(StatRecording.class,true);
		// Collections.sort(records);
		Iterator it = records.iterator();
		while (it.hasNext()) {
			Recording record = (Recording) it.next();
				data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), src.isActiveRecordingOnSource(record) });
			}
		
		
		model = new logdruid.ui.mainpanel.StatRecordingSelectorPanel.MyTableModel(data, header);

		StatRecordingSelectorPanel thiis = this;
		logger.debug("source is " + ((source == null) ? "null" : src.getSourceName()));
		setLayout(new BorderLayout(0, 0));

		JPanel panel_1 = new JPanel();
		panel_1.setLayout(new BorderLayout(0, 0));

		table = new JTable(model);
		JScrollPane scrollPane = new JScrollPane(table);
		panel_1.add(scrollPane, BorderLayout.CENTER);

		table.setPreferredScrollableViewportSize(new Dimension(0, 150));
		table.setFillsViewportHeight(true);
		table.setAutoCreateRowSorter(true);
		// Set up column sizes.
		initColumnSizes(table);

		JSplitPane splitPane = new JSplitPane();
		splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
		add(splitPane);

		jPanelDetail = new JPanel();
		splitPane.setBottomComponent(jPanelDetail);
		splitPane.setTopComponent(panel_1);
		jPanelDetail.setLayout(new BorderLayout(0, 0));
		table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

			public void valueChanged(ListSelectionEvent e) {
				int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
				logger.debug("ListSelectionListener - selectedRow: " + selectedRow);
				if (selectedRow >= 0) {
					if (jPanelDetail != null) {
						logger.debug("ListSelectionListener - valueChanged");
						jPanelDetail.removeAll();
						recEditor = getEditor(repository.getRecording(StatRecording.class, selectedRow,true));
						if (recEditor != null) {
							jPanelDetail.add(recEditor, BorderLayout.CENTER);
						}
						jPanelDetail.revalidate();
					}
				}
			}
		});
		if (repository.getRecordings(StatRecording.class,true).size() > 0) {
			recEditor = getEditor(repository.getRecording(StatRecording.class,0,true));
			jPanelDetail.add(recEditor, BorderLayout.CENTER);
			table.setRowSelectionInterval(0, 0);
		}
		if (model.getRowCount()>0){
			table.getRowSorter().toggleSortOrder(0);
			table.setRowSelectionInterval(0, 0);
			
		}
	}

	private JPanel getEditor(Recording rec) {
		return new StatRecordingEditor(this,repository, rec.getExampleLine(), rec.getRegexp(), ((StatRecording) rec));
	}
/*
	public void reloadTable() {
		int selectedRow = ((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1);
		records = repository.getRecordings(StatRecording.class);
		logger.debug("reloadTable - nb records : " + records.size());
		// Collections.sort(records);
		Iterator it = records.iterator();
		int count = 0;
		data.clear();
		// this.repaint();

		logger.debug("reloadTable - 1");
		while (it.hasNext()) {
			Recording record = (Recording) it.next();
			data.add(new Object[] { record.getName(), record.getRegexp(), record.getType(), record.getIsActive() });
			logger.debug(count + record.getName() + record.getRegexp() + record.getIsActive());
		}
		// model.fireTableDataChanged();
		logger.debug("reloadTable - 2");
		// this.repaint();
		table.repaint();

		logger.debug("reloadTable - 3");
		this.revalidate();

	}
*/
	private void initColumnSizes(JTable theTable) {
		TableColumn column = null;
		Component comp = null;
		int headerWidth = 0;
		int cellWidth = 0;
		TableCellRenderer headerRenderer = theTable.getTableHeader().getDefaultRenderer();

		for (int i = 0; i < 4; i++) {
			column = theTable.getColumnModel().getColumn(i);
			comp = headerRenderer.getTableCellRendererComponent(null, column.getHeaderValue(), false, false, 0, 0);
			headerWidth = comp.getPreferredSize().width;
			cellWidth = comp.getPreferredSize().width;
			column.setPreferredWidth(Math.max(headerWidth, cellWidth));
		}
	}

	public class MyTableModel extends AbstractTableModel {
		private String[] header;
		private ArrayList<Object[]> data;

		public MyTableModel(ArrayList<Object[]> data, String[] header) {
			this.header = header;
			this.data = data;
		}

		@Override
		public int getColumnCount() {
			if (header == null) {
				return 0;
			} else
				return header.length;
		}

		@Override
		public String getColumnName(int column) {
			return header[column];
		}

		@Override
		public int getRowCount() {
			return repository.getRecordings(StatRecording.class,true).size();
		}

		@Override
		public Object getValueAt(int row, int column) {
			if (column == 0 ) {
				return repository.getRecording(StatRecording.class,row,true).getName();
			} else if (column == 1 ) {
				return repository.getRecording(StatRecording.class,row,true).getRegexp();
			} else if (column == 2 ) {
				return repository.getRecording(StatRecording.class,row,true).getType();
			} else if (column == 3 ) {
				logger.debug("getvalueat name" + ((StatRecording) repository.getRecording(StatRecording.class, row,true)).getName());
				logger.debug("getvalueat is active" + source.isActiveRecordingOnSource(repository.getRecording(StatRecording.class, row,true)));
				return source.isActiveRecordingOnSource(repository.getRecording(StatRecording.class, row,true));
			}
			else return 0;
		}

		public void addRow(Object[] obj) {
			data.add(obj);
	//		table.repaint();
		}

		public void updateRow(int rowId, Object[] obj) {
			data.set(rowId, obj);
//			table.repaint();
		}

		@Override
		public void setValueAt(Object value, int row, int column) {
			if (column == 3 && source != null) {
				logger.debug("setValueAt calls setActiveRecording");
				source.toggleActiveRecording(repository.getRecording(StatRecording.class, row,true));
				fireTableCellUpdated(row, column);
				// logger.debug("control of setValueAt: "+source.isActiveRecordingOnSource(repository.getRecording(MetadataRecording.class,
				// row)));
			} else {
				((Object[]) data.get(row))[column] = value;
				fireTableCellUpdated(row, column);
			}
			table.repaint();
		}

		/*
		 * @Override public void setValueAt(Object value, int row, int column) {
		 * data.get(row)[column] = value; fireTableCellUpdated(row, column); }
		 */
		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			return getValueAt(0, c).getClass();
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			// Note that the data/cell address is constant,
			// no matt&er where the cell appears onscreen.
			if (col > 2) {
				return true;
			} else {
				return false;
			}
		}
	}

	public void Add() {
		data.add(new Object[] { "", ".*", "long", Boolean.FALSE });
		table.repaint();
	}

	/*
	 * public void Remove() {
	 * data.remove(((table.getSelectedRow()!=-1)?table.convertRowIndexToModel
	 * (table.getSelectedRow()):-1)); table.repaint(); }
	 */

	public void Remove() {
		data.remove(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		repository.deleteRecording(((table.getSelectedRow() != -1) ? table.convertRowIndexToModel(table.getSelectedRow()) : -1));
		table.repaint();
	}
}
 public class DataMiner {
	private static Logger logger = Logger.getLogger(DataMiner.class.getName());
	static List<File> listOfFiles = null;
	private static ExecutorService ThreadPool_FileWorkers = null;
	private static ExecutorService ThreadPool_GroupWorkers = null;
	static long estimatedTime = 0;
	static long startTime = 0;
	static final Map<Source, Map<Recording, Map<List<Object>, Long>>> occurenceReport = new ConcurrentHashMap<Source, Map<Recording, Map<List<Object>, Long>>>();
	static final Map<Source, Map<Recording, Map<List<Object>, Double>>> sumReport = new ConcurrentHashMap<Source, Map<Recording, Map<List<Object>, Double>>>();
	static final Map<Source, Map<Recording, SortedMap<Double,List<Object>>>> top100Report = new ConcurrentHashMap<Source, Map<Recording, SortedMap<Double,List<Object>>>>();;
	
	public static MineResultSet gatherMsineResultSet(ChartData cd, final Repository repo, final MainFrame mainFrame) {
		String test = Preferences.getPreference("ThreadPool_Group");
		int ini = Integer.parseInt(test);
		logger.info("gatherMineResultSet parallelism: " + ini);
		ThreadPool_GroupWorkers = Executors.newFixedThreadPool(ini);
	//	ChartData cd = new ChartData();
		Collection<Callable<MineResult>> tasks = new ArrayList<Callable<MineResult>>();
		MineResultSet mineResultSet = new MineResultSet();
		occurenceReport.clear();
		sumReport.clear();
		top100Report.clear();
		// tOP100Report = new ConcurrentHashMap<Recording,Map<String, Long>>();

		startTime = System.currentTimeMillis();
	/*	try {
			cd = gatherSourceData(repo);
		} catch (Exception e) {
			return null;
		}*/
		
		// if (logger.isEnabledFor(Level.INFO))
		// logger.info("ArrayList sourceFileGroup" + sourceFileGroup);
		Iterator<Source> sourceIterator2 = repo.getSources().iterator();
		int progressCount = 0;
		while (sourceIterator2.hasNext()) {
			final Source source = sourceIterator2.next();
			// sourceFiles contains all the matched files for a given source
			if (source.getActive() && source.getActiveMetadata()!=null) {
				Iterator<Entry<String, ArrayList<FileRecord>>> it = cd.getGroupFilesMap(source).entrySet().iterator();
				while (it.hasNext()) {
					final Map.Entry<String, ArrayList<FileRecord>> pairs = it.next();
					progressCount = progressCount + pairs.getValue().size();
					logger.debug("Source:" + source.getSourceName() + ", group: " + pairs.getKey() + " = " + pairs.getValue().toString());
					tasks.add(new Callable<MineResult>() {
						public MineResult call() throws Exception {
							return DataMiner.mine(pairs.getKey(), pairs.getValue(), repo, source, Preferences.isStats(),
									Preferences.isTimings(), Preferences.isMatches(), mainFrame);
						}

					});

				}
			}
		}
		mainFrame.setMaxProgress(progressCount);
		// logger.info("progressCount "+ progressCount);
		/*
		 * invokeAll blocks until all service requests complete, or a max of
		 * 1000 seconds.
		 */
		List<Future<MineResult>> results = null;
		try {
			results = ThreadPool_GroupWorkers.invokeAll(tasks, 100000, TimeUnit.SECONDS);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (Future<MineResult> f : results) {
			MineResult mineRes = null;
			try {
				// if (mineRes!=null)
				mineRes = f.get();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (mineRes != null) {
				mineResultSet.updateStartDate(mineRes.getStartDate());
				mineResultSet.updateEndDate(mineRes.getEndDate());
				if (!mineResultSet.mineResults.keySet().contains(mineRes.getSource())) {
					mineResultSet.mineResults.put(mineRes.getSource(), new HashMap<String, MineResult>());
				}
				mineResultSet.mineResults.get(mineRes.getSource()).put(mineRes.getSource().getSourceName() + mineRes.getGroup(), mineRes);
			}
		}
		estimatedTime = System.currentTimeMillis() - startTime;
		logger.info("gathering time: " + estimatedTime);
		/*
		 * Iterator oRIte= occurenceReport.keySet().iterator(); while
		 * (oRIte.hasNext()) { String occString=(String) oRIte.next();
		 * logger.info("nb: "+ occurenceReport.get(occString)+" string: "
		 * +occString); }
		 */
		mineResultSet.setOccurenceReport(occurenceReport);
		mineResultSet.setTop100Report(top100Report);
		mineResultSet.setSumReport(sumReport);	

		return mineResultSet;

	}
	
	// handle gathering for ArrayList of file for one source-group
	public static MineResult mine(String group, ArrayList<FileRecord> arrayList, final Repository repo, final Source source, final boolean stats, final boolean timings,
			final boolean matches, final MainFrame mainFrame) {
		logger.debug("call to mine for source " + source.getSourceName() + " on group " + group);
		ThreadPool_FileWorkers = Executors.newFixedThreadPool(Integer.parseInt(Preferences.getPreference("ThreadPool_File")));
		Date startDate = null;
		Date endDate = null;
		// Map<String, ExtendedTimeSeries> statMap = HashObjObjMaps<String,
		// ExtendedTimeSeries>();
		Map<String, ExtendedTimeSeries> statMap = new HashMap<String, ExtendedTimeSeries>();
		Map<String, ExtendedTimeSeries> eventMap = new HashMap<String, ExtendedTimeSeries>();
		Map<String, long[]> timingStatsMap = new HashMap<String, long[]>();
		Map<String, Map<Date, FileLine>> fileLine = new HashMap<String, Map<Date, FileLine>>();
		Collection<Callable<FileMineResult>> tasks = new ArrayList<Callable<FileMineResult>>();
		
		final Map<Recording, String> recMatch1 = getAllRegexSingleMap(repo, source); 

		ArrayList<Object> mapArrayList;
		mapArrayList = new ArrayList<>();
		if (logger.isEnabledFor(Level.INFO))
			logger.info("mine called on " + source.getSourceName());
		Iterator<FileRecord> fileArrayListIterator = arrayList.iterator();
		while (fileArrayListIterator.hasNext()) {
			final FileRecord fileRec = fileArrayListIterator.next();
			tasks.add(new Callable<FileMineResult>() {
				public FileMineResult call() throws Exception {
					logger.debug("file mine on " + fileRec);
					return fileMine(fileRec, recMatch1, repo, source, stats, timings, matches, mainFrame);
				}

			});

		}
		List<Future<FileMineResult>> results = null;
		try {
			results = ThreadPool_FileWorkers.invokeAll(tasks, 100000, TimeUnit.SECONDS);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		for (Future<FileMineResult> f : results) {
			FileMineResult fileMineRes = null;
			try {
				if (f != null) {
					fileMineRes = f.get();
				}
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (ExecutionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (NullPointerException e) {
				// TODO Auto-generated catch block
				// e.printStackTrace();
			}
			if (fileMineRes != null) {
				mapArrayList.add(fileMineRes);
			}

		}
		ArrayList<Object[]> fileDates = new ArrayList<Object[]>();
		Iterator<Object> mapArrayListIterator = mapArrayList.iterator();
		while (mapArrayListIterator.hasNext()) {
			FileMineResult fMR = (FileMineResult) mapArrayListIterator.next();

			if (startDate == null) {
				startDate = fMR.getStartDate();
			}
			if (endDate == null) {
				endDate = fMR.getEndDate();
			}
			if (fMR.getEndDate() != null && fMR.getStartDate() != null) {
				if (fMR.getEndDate().after(endDate)) {
					endDate = fMR.getEndDate();
				} else if (fMR.getStartDate().before(startDate)) {
					startDate = fMR.getStartDate();
				}
				if (logger.isDebugEnabled()) {
					logger.debug("1: " + fMR.getStartDate() + "2: " + fMR.getEndDate() + "3: " + fMR.getFile());
				}
				fileDates.add(new Object[] { fMR.getStartDate(), fMR.getEndDate(), fMR.getFile() });
			}

			Map<String, ExtendedTimeSeries> tempStatMap = fMR.statGroupTimeSeries;
			tempStatMap.entrySet();
			Iterator it = tempStatMap.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry<String, ExtendedTimeSeries> pairs = (Map.Entry<String, ExtendedTimeSeries>) it.next();
				if (!statMap.containsKey(pairs.getKey())) {
					statMap.put(pairs.getKey(), pairs.getValue());
				} else {
					ExtendedTimeSeries ts = statMap.get(pairs.getKey());
					if (stats) {
						int[] array = { pairs.getValue().getStat()[0] + ts.getStat()[0], pairs.getValue().getStat()[1] + ts.getStat()[1] };
						ts.setStat(array);
					}
					ts.getTimeSeries().addAndOrUpdate(pairs.getValue().getTimeSeries());
					statMap.put(pairs.getKey(), ts);
					// logger.info(pairs.getKey());
				}
			}

			Map tempEventMap = fMR.eventGroupTimeSeries;
			tempEventMap.entrySet();
			it = tempEventMap.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry<String, ExtendedTimeSeries> pairs = (Map.Entry<String, ExtendedTimeSeries>) it.next();
				if (!eventMap.containsKey(pairs.getKey())) {
					eventMap.put(pairs.getKey(), pairs.getValue());
				} else {
					ExtendedTimeSeries ts = eventMap.get(pairs.getKey());
					if (stats) {
						int[] array = { pairs.getValue().getStat()[0] + ts.getStat()[0], pairs.getValue().getStat()[1] + ts.getStat()[1] };
						ts.setStat(array);
					}
					ts.getTimeSeries().addAndOrUpdate(pairs.getValue().getTimeSeries());
					eventMap.put(pairs.getKey(), ts);
				}
			}

			it = fMR.matchingStats.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry<String, long[]> pairs = (Map.Entry<String, long[]>) it.next();
				if (!timingStatsMap.containsKey(pairs.getKey())) {
					timingStatsMap.put(pairs.getKey(), pairs.getValue());
				} else {
					long[] array = timingStatsMap.get(pairs.getKey());
					// 0-> sum of time for success matching of given
					// recording ; 1-> sum of time for failed
					// matching ; 2-> count of match attempts,
					// 3->count of success attempts
					long[] array2 = { pairs.getValue()[0] + array[0], pairs.getValue()[1] + array[1], pairs.getValue()[2] + array[2],
							pairs.getValue()[3] + array[3] };
					timingStatsMap.put(pairs.getKey(), array2);
				}
			}
			it = fMR.fileLineDateMap.entrySet().iterator();
			while (it.hasNext()) {
				Map.Entry<String, Map<Date, FileLine>> pairs = (Map.Entry<String, Map<Date, FileLine>>) it.next();
				if (logger.isDebugEnabled()) {
					logger.debug("Entry<String,Map<Date, FileLine>> : " + pairs);
				}
				if (!fileLine.containsKey(pairs.getKey())) {
					fileLine.put(pairs.getKey(), pairs.getValue());
					if (logger.isDebugEnabled()) {
						logger.debug("groupFileLineMap.put " + pairs.getKey() + " -> " + pairs.getValue());
					}
				} else {
					Map<Date, FileLine> ts = fileLine.get(pairs.getKey());
					Map<Date, FileLine> newDateFileLineEntries = pairs.getValue();
					Iterator it2 = newDateFileLineEntries.entrySet().iterator();
					while (it2.hasNext()) {
						Map.Entry<Date, FileLine> pairs2 = (Map.Entry<Date, FileLine>) it2.next();
						fileLine.get(pairs.getKey()).put(pairs2.getKey(), pairs2.getValue());
						if (logger.isDebugEnabled()) {
							logger.debug("groupFileLineMap.put " + pairs2.getKey() + " -> " + pairs2.getValue().getFileId() + ":" + pairs2.getValue().getLineNumber());
						}
					}
					// logger.info("cont2: "+groupFileLineMap.get(pairs.getKey()));
				}

			}

		}
		
		FileMineResultSet fMRS = new FileMineResultSet(fileDates, statMap, eventMap, timingStatsMap, fileLine, startDate, endDate);
		return new MineResult(group, fMRS, arrayList, repo, source);
	}

	public static String readFileLine(Source src, FileLine fileLine, ChartData cd) {
		FileReader flstr = null;
		String line = "";
		FileRecord fileRecord = cd.sourceFileArrayListMap.get(src).get(fileLine.getFileId());
		try {
			flstr = new FileReader(fileRecord.getCompletePath());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		BufferedReader r = new BufferedReader(flstr);
		for (int i = 0; i < fileLine.getLineNumber(); i++) {
			try {
				line = r.readLine();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return line;

	}

	// handle gathering for a single file
	public static FileMineResult fileMine(FileRecord fileRecord, Map<Recording, String> recMatch1, Repository repo, Source source, boolean stats, boolean timings, boolean matches,
			final MainFrame mainFrame) {
		ExtendedTimeSeries ts = null;
		PatternCache patternCache = new PatternCache();
		ClassCache classCache = new ClassCache();
		Date startDate = null;
		Date endDate = null;
		DecimalFormat decimalFormat = new DecimalFormat("#.#", new DecimalFormatSymbols(Locale.US));
		java.text.DateFormat fastDateFormat = null;
		FileReader flstr = null;
		BufferedReader buf1st;
		Matcher matcher;
		Matcher matcher2;
		FixedMillisecond fMS = null;
		DateFormat df = null;
		int statHit = 0;
		int statMatch = 0;
		int eventHit = 0;
		int eventMatch = 0;
		long[] arrayBefore;
		long match0 = 0;
		long match1 = 0;
		long timing0 = 0;
		long timing1 = 0;
		Map<Recording, String> recMatch = new HashMap<Recording, String>(recMatch1);
		Map<String, ExtendedTimeSeries> statMap = new HashMap<String, ExtendedTimeSeries>();
		Map<String, ExtendedTimeSeries> eventMap = new HashMap<String, ExtendedTimeSeries>();
		Map<String, Map<Date, FileLine>> RIFileLineDateMap = new HashMap<String, Map<Date, FileLine>>();
		Map<String, long[]> matchTimings = new HashMap<String, long[]>();
		boolean gatherStats = Preferences.getBooleanPreference("gatherstats");
		boolean gatherReports = Preferences.getBooleanPreference("gatherreports");
		boolean gatherEvents = Preferences.getBooleanPreference("gatherevents");
		long recordingMatchStart = 0;
		long recordingMatchEnd = 0;
		try {
			if (logger.isDebugEnabled()) {
				logger.debug("++file: " + repo.getBaseSourcePath() + " + " + (String) fileRecord.getCompletePath().toString());
			}
			flstr = new FileReader(fileRecord.getCompletePath());
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}

		if (!occurenceReport.containsKey(source)) {
			occurenceReport.put(source, new ConcurrentHashMap<Recording, Map<List<Object>, Long>>());
		}
		if (!top100Report.containsKey(source)) {
			top100Report.put(source, new ConcurrentHashMap<Recording, SortedMap<Double,List<Object>>>());
		}
		
		if (!sumReport.containsKey(source)) {
			sumReport.put(source, new ConcurrentHashMap<Recording, Map<List<Object>, Double>>());
		}
		
		buf1st = new BufferedReader(flstr);
		String line;
		try {
			//recMatch = getRegexp(repo, source);
			int lineCount = 1;
			while ((line = buf1st.readLine()) != null) {
				// check against one Recording pattern at a tim
				// if (logger.isDebugEnabled()) {
				// logger.debug("line " + line);
				// }
				Iterator<Entry<Recording, String>> recMatchIte = recMatch.entrySet().iterator();
				while (recMatchIte.hasNext()) {
					if (timings) {
						recordingMatchStart = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
					}
					Entry<Recording, String> me = recMatchIte.next();
					Recording rec = (Recording) me.getKey();
					matcher = patternCache.getMatcher((String) (rec.getRegexp()),rec.isCaseSensitive(),line);
					if (matcher.find()) {
						Boolean isStatRecording = classCache.getClass(rec).equals(StatRecording.class);
						if (stats) {
							if (isStatRecording) {
								statMatch++;
							} else {
								eventMatch++;
							}
						}
						// logger.info("1**** matched: " + line);
						ArrayList<RecordingItem> recordingItem = ((Recording) rec).getRecordingItem();
						matcher2 = patternCache.getMatcher((String) me.getValue(),rec.isCaseSensitive(),line);
						if (matcher2.find()) {
							if (stats) {
								if (isStatRecording) {
									statHit++;
								} else {
									eventHit++;
								}
							}
							if (!classCache.getClass(rec).equals(ReportRecording.class)) {
								int count = 1;
								Date date1 = null;
								// handling capture for each recording item
								Iterator<RecordingItem> recItemIte2 = recordingItem.iterator();
								while (recItemIte2.hasNext()) {
									RecordingItem recItem2 = recItemIte2.next();
									// logger.info("3A**** " +
									// recItem2.getType());
									if (recItem2.getType().equals("date")) {
										try {
											df = repo.getDateFormat(rec.getDateFormatID());
											if (logger.isDebugEnabled())
												logger.debug("4**** rec name" + rec.getName() + " df: " + df.getId());
											fastDateFormat =ThreadLocalDateFormatMap.getInstance().createSimpleDateFormat(df.getDateFormat());
										//	fastDateFormat = FastDateFormat.getInstance(df.getDateFormat());
											date1 = fastDateFormat.parse(matcher2.group(count));
											if (logger.isDebugEnabled())
												logger.debug("4b**** " + df.getDateFormat() + " date: " + date1.toString());
											// logger.info("4**** " +
											// date1.toString());
										} catch (ParseException e) {
											// TODO Auto-generated catch
											// block
											e.printStackTrace();
										}
									} else if (date1 != null) {
										if (recItem2.isSelected()) {
											if (logger.isDebugEnabled()) {
												logger.debug("FileRecord: " + fileRecord.getFile().getName() + ", Source: " + source.getSourceName() + ", "
														+ recItem2.getName() + ", " + fileRecord.getFile().getName() + ", " + lineCount);
											}
											// recording line of match in file
											// in map RIFileLineDateMap - note
											// the FileLine object use an int to
											// identify the files to save memory
											Map<Date, FileLine> dateFileLineMap = null;
											//change this to recItem2 to differentiate recording items with same name ?? TBD
											//if (RIFileLineDateMap.containsKey(recItem2.getName())) {
												dateFileLineMap = RIFileLineDateMap.get(recItem2.getName());
												if (dateFileLineMap==null){
													dateFileLineMap = new HashMap<Date, FileLine>();
												}
													dateFileLineMap.put(date1, new FileLine(fileRecord.getId(), lineCount));
											if (logger.isDebugEnabled()) {
												logger.debug(fileRecord.getFile().getName() + " dateFileLineMap put: " + date1 + "groupFileLineMap: "
														+ new FileLine(fileRecord.getId(), lineCount));
												logger.debug(fileRecord.getFile().getName() + " FileRecord: " + fileRecord.getFile().getName()
														+ ", RIFileLineDateMap.put: " + recItem2.getName() + ", line: " + lineCount
														+ " RIFileLineDateMap size: " + RIFileLineDateMap.size() + " dateFileLineMap size: "
														+ dateFileLineMap.size());
											}
											RIFileLineDateMap.put(recItem2.getName(), dateFileLineMap);

											if (startDate == null) {
												startDate = date1;
											}
											if (endDate == null) {
												endDate = date1;
											}
											if (date1.after(startDate)) {
												endDate = date1;
											} else if (date1.before(startDate)) {
												startDate = date1;
											}

											if (isStatRecording && (gatherStats)) {
													ts = statMap.get(recItem2.getName());
												 if (ts==null) {
													ts = new ExtendedTimeSeries(recItem2, FixedMillisecond.class);
													if (logger.isDebugEnabled())
														logger.debug("5**** Adding record to Map: " + recItem2.getName());
												}
												fMS = new FixedMillisecond(date1);
												if (matcher2.group(count) == null) {
													logger.info("null in match on " + recItem2.getName() + " at " + fileRecord.getFile().getName()
															+ " line cnt:" + lineCount);
													logger.info("line : " + line);
												}
												if (recItem2.getType().equals("long")) {
													ts.getTimeSeries().addOrUpdate((new TimeSeriesDataItem(fMS, Long.valueOf((String) matcher2.group(count)))));
												} else {
													try {
														ts.getTimeSeries().addOrUpdate(
																(new TimeSeriesDataItem(fMS, Double.parseDouble(String.valueOf(decimalFormat
																		.parse((String) matcher2.group(count).replace(',', '.')))))));
													} catch (Exception e) {
														e.printStackTrace();
													}

												}

												if (stats) {
													int[] array = ts.getStat();
													array[1] = array[1] + 1;
													array[0] = array[0] + 1;
													ts.setStat(array);
													if (logger.isDebugEnabled())
														logger.debug("stats " + array[0] + " " + array[1]);
												}
												statMap.put(recItem2.getName(), ts);
												// performance: add the
												// TmeSeriesDataItem to the
												// TimeSeries instead of
												// updating
												// the TimeSeries in the Map

											} else if (classCache.getClass(rec).equals(EventRecording.class) &&  (gatherEvents )) {
												ts = eventMap.get(recItem2.getName());
												if (ts==null) {
													ts = new ExtendedTimeSeries(recItem2, FixedMillisecond.class);
													if (logger.isDebugEnabled())
														logger.debug("5**** Adding record to Map: " + recItem2.getName());
												}
										//		SimpleTimePeriod stp = new SimpleTimePeriod(date1,DateUtils.addMilliseconds(date1,1));
												fMS = new FixedMillisecond(date1);

												if (((RecordingItem) recItem2).getProcessingType().equals("occurrences")) {
													TimeSeriesDataItem t = ts.getTimeSeries().getDataItem(fMS);
													if (t != null) {
														ts.getTimeSeries().addOrUpdate((new TimeSeriesDataItem(fMS, (double)t.getValue()+1))); // +
														// (double)t.getValue()
														// need some way to show
														// several occurrences
													} else {
														ts.getTimeSeries().add((new TimeSeriesDataItem(fMS, 1)));
													}

												} else if (((RecordingItem) recItem2).getProcessingType().equals("duration")) {
													try {
														ts.getTimeSeries().addOrUpdate(
																(new TimeSeriesDataItem(fMS, Double.parseDouble(String.valueOf(decimalFormat.parse(matcher2
																		.group(count)))))));
													} catch (ParseException e) {
														// TODO
														// Auto-generated
														// catch block
														e.printStackTrace();
													}
												
												// ts.addOrUpdate((new
												// TimeSeriesDataItem(fMS,
												// 100)));
											} else if (((RecordingItem) recItem2).getProcessingType().equals("sum")) {
													TimeSeriesDataItem t = ts.getTimeSeries().getDataItem(fMS);
													if (t != null) {
														if (!recItem2.getType().equals("date")) {
															try {
																ts.getTimeSeries().addOrUpdate(
																		(new TimeSeriesDataItem(fMS,
																				Double.parseDouble(String.valueOf(decimalFormat.parse(matcher2.group(count)))
																						+ ts.getTimeSeries().getDataItem(fMS).getValue()))));
																logger.info(ts.getTimeSeries().getDataItem(fMS).getValue());
															} catch (ParseException e) {
																// TODO
																// Auto-generated
																// catch block
																e.printStackTrace();
															}
														}
													} else {
														try {
															// to improve - should use the right type here
															ts.getTimeSeries().add(
																	(new TimeSeriesDataItem(fMS, Double.parseDouble(String.valueOf(decimalFormat.parse(matcher2
																			.group(count)))))));
														} catch (ParseException e) {
															// TODO
															// Auto-generated
															// catch block
															e.printStackTrace();
														}
													}

												} else if (((RecordingItem) recItem2).getProcessingType().equals("capture")) {
													
												} 
												// logger.debug(recItem2.getName()
												// +
												// " " +
												// Double.parseDouble((matcher2.group(count))));
												if (stats) {
													int[] array = ts.getStat();
													array[1] = array[1] + 1;
													array[0] = array[0] + 1;
													ts.setStat(array);
													if (logger.isDebugEnabled())
														logger.debug("stats " + array[0] + " " + array[1]);
												}
												eventMap.put(recItem2.getName(), ts);

											}

										}
									} // rec.getClass().equals(ReportRecording.class)

									count++;
									// logger.info("event statistics: "+eventMatch
									// +
									// " and " +eventHit +
									// " ; stat statistics: "+statMatch +
									// " and "
									// +statHit);
								}
							} else { if (gatherReports){
								int count = 0;
								if (((ReportRecording) rec).getSubType().equals("histogram") && rec.getIsActive()) {
									List<Object> temp = new ArrayList<Object>();
									Iterator<RecordingItem> recItemIte2 = recordingItem.iterator();
									while (recItemIte2.hasNext()) {
										RecordingItem recItem2 = recItemIte2.next();
										if (recItem2.isSelected()) {
											temp.add(matcher2.group(count + 1));
										}
										count++;
									}
									Map<List<Object>,Long>  occMap = occurenceReport.get(source).get(rec);
									if (occMap==null) {
										occurenceReport.get(source).put(rec, new ConcurrentHashMap<List<Object>, Long>());
										occMap = occurenceReport.get(source).get(rec);
									}
									synchronized (occMap) {
									Object occ = occMap.get(temp);
									
									if (occ==null) {
										occMap.put(temp, (long) 1);
									} else {
										occMap.put(temp, (long) occ + 1);
									}
									}
								} else if (((ReportRecording) rec).getSubType().equals("top100") && rec.getIsActive()) {
									double itemIndex = 0;

									SortedMap<Double,List<Object>> t100 = top100Report.get(source).get(rec);
									if (t100==null) {
										top100Report.get(source).put(rec, Collections.synchronizedSortedMap(new TreeMap<Double,List<Object>>()));
										t100 = top100Report.get(source).get(rec);
									}
									try {
									itemIndex = (double)Double.valueOf(matcher2.group(((ReportRecording) rec).getTop100RecordID()+1));
									} catch (NullPointerException npe){										
										//nothing
									}		
									catch (NumberFormatException nfe){
										//nothing
										logger.info(matcher2.group(0));
										logger.info(matcher2.group(((ReportRecording) rec).getTop100RecordID()+1));
									}
									synchronized (t100) {
									if (t100.size()<100){			
										List<Object> temp = new ArrayList<Object>();
										Iterator<RecordingItem> recItemIte2 = recordingItem.iterator();
										while (recItemIte2.hasNext()) {
											RecordingItem recItem2 = recItemIte2.next();
											if (recItem2.isSelected()) {
												if (recItem2.getProcessingType().equals("top100")){
												itemIndex=(double)Double.valueOf(matcher2.group(count + 1));
												} else {
												temp.add(matcher2.group(count + 1));
												}}
											count++;
										}	
										t100.put(itemIndex, temp);
									}
									else if (t100.size()==100){
											if (itemIndex>t100.firstKey()){
												List<Object> temp = new ArrayList<Object>();
												Iterator<RecordingItem> recItemIte2 = recordingItem.iterator();
												while (recItemIte2.hasNext()) {
													RecordingItem recItem2 = recItemIte2.next();
													if (recItem2.isSelected()) {
														if (recItem2.getProcessingType().equals("top100")){
														itemIndex=(double)Double.valueOf(matcher2.group(count + 1));
														} else {
														temp.add(matcher2.group(count + 1));
														}}
													count++;
												}												
												t100.remove(t100.firstKey());
												t100.put(itemIndex, temp);	
											}											
										}

									} 
								}
								
								else if (((ReportRecording) rec).getSubType().equals("sum") && rec.getIsActive()) {
									double itemIndex = 0;
									List<Object> temp = new ArrayList<Object>();
									Iterator<RecordingItem> recItemIte2 = recordingItem.iterator();
									while (recItemIte2.hasNext()) {
										RecordingItem recItem2 = recItemIte2.next();
										if (recItem2.isSelected()) {
											if (recItem2.getProcessingType().equals("sum")){
											itemIndex=(double)Double.valueOf(matcher2.group(count + 1));
											} else {
											temp.add(matcher2.group(count + 1));
											}}
										count++;
									}
									Map<List<Object>,Double>  sumMap = sumReport.get(source).get(rec);
									if (sumMap==null) {
										sumReport.get(source).put(rec, new ConcurrentHashMap<List<Object>, Double>());
										sumMap = sumReport.get(source).get(rec);
									}
									synchronized (sumMap) {
									Object sum = sumMap.get(temp);
									
									if (sum==null) {
										sumMap.put(temp, (double)itemIndex);
									} else {
										sumMap.put(temp, (double) sum + itemIndex);
									}
									}
								}
							}
							}
						}
						if (timings || matches) {
								arrayBefore = matchTimings.get(rec.getName());
								if (arrayBefore!=null) {
								// logger.info(file.getName() + " contains " +
								// arrayBefore);
								// 0-> sum of time for success matching of given
								// recording ; 1-> sum of time for failed
								// matching ; 2-> count of match attempts,
								// 3->count of success attempts
								if (timings) {
									recordingMatchEnd = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
									timing0 = arrayBefore[0] + recordingMatchEnd - recordingMatchStart;
									timing1 = arrayBefore[1];
								}
								if (matches) {
									match0 = arrayBefore[2] + 1;
									match1 = arrayBefore[3] + 1;
								}
								long[] array = { timing0, timing1, match0, match1 };
								matchTimings.put(rec.getName(), array);
							} else {
								if (timings) {
									recordingMatchEnd = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
									long[] array = { recordingMatchEnd - recordingMatchStart, 0, 1, 1 };
									matchTimings.put(rec.getName(), array);
								}else {
									long[] array = { 0, 0, 1, 1 };
									matchTimings.put(rec.getName(), array);
								}
							}
						}
					} else {
						if (timings || matches) {
								arrayBefore = matchTimings.get(rec.getName());
								if (arrayBefore!=null) {
								// logger.info(file.getName() + " contains " +
								// arrayBefore);
								// 0-> sum of time for success matching of given
								// recording ; 1-> sum of time for failed
								// matching ; 2-> count of match attempts,
								// 3->count of success attempts
								if (timings) {
									recordingMatchEnd = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
									timing0 = arrayBefore[0];
									timing1 = arrayBefore[1] + recordingMatchEnd - recordingMatchStart;
								}
								if (matches) {
									match0 = arrayBefore[2] + 1;
									match1 = arrayBefore[3];
								}
								long[] array = { timing0, timing1, match0, match1 };
								matchTimings.put(rec.getName(), array);
							} else {
								if (timings) {
									recordingMatchEnd = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
									long[] array = { 0, recordingMatchEnd - recordingMatchStart, 1, 0 };
									matchTimings.put(rec.getName(), array);
								} else{
									long[] array = { 0, 0, 1, 0 };
									matchTimings.put(rec.getName(), array);
								}
							}
						}
					}
				}
				lineCount++;

				// timing
			}
		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				buf1st.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		mainFrame.progress();
		return new FileMineResult(fileRecord, statMap, eventMap, matchTimings, RIFileLineDateMap, startDate, endDate);
	}

	/*
	 * public Map<String,ArrayList> getSourceFileGroup(ArrayList<String>
	 * sourceFiles,Source src) { String patternString = "";
	 * Map<String,ArrayList> Map=new
	 * Map<String,ArrayList>(); while (it.hasNext()){ it.next(); }}
	 * 
	 * returns Map with group id in key and a ArrayList of matching files in
	 * value.
	 * 
	 * @param repo
	 */
	public static Map<String, ArrayList<FileRecord>> getSourceFileGroup(Map<Integer, FileRecord> sourceFiles, Source src, Repository repo, boolean order) {
		PatternCache patternCache = new PatternCache();
		String patternString = "";
		Map<String, ArrayList<FileRecord>> sourceFileGroup = new HashMap<String, ArrayList<FileRecord>>();
		ArrayList<FileRecord> groupedFiles = new ArrayList<FileRecord>();
		Matcher matcher = null;
		Recording rec = src.getActiveMetadata();
		if (src!=null && rec!=null){
					ArrayList<RecordingItem> rIV = ((MetadataRecording) rec).getRecordingItem();
					Iterator<RecordingItem> itV = rIV.iterator();
					int nbRec = 0;
					while (itV.hasNext()) {
						RecordingItem rI = itV.next();
						String type = rI.getType();
						if (type == "date") {
							patternString += rI.getBefore() + "(" + repo.getDateFormat(rec.getDateFormatID()) + ")" + rI.getAfter();
						} else {
							patternString += rI.getBefore() + "(" + DataMiner.getTypeString(type) + ")" + rI.getAfter();
						}
						// logger.info("patternString: " + patternString
						// + " getType: " +
						// DataMiner.getTypeString(rI.getType()));
						nbRec++;
					}
					Iterator<FileRecord> sourceFileIterator = sourceFiles.values().iterator();
					String key = "";
					// tempV = new ArrayList<String>();
					while (sourceFileIterator.hasNext()) {
						groupedFiles.clear();
						FileRecord fileName = sourceFileIterator.next();
						// logger.info("file: "+fileName);
						try {

							if (logger.isTraceEnabled()){
								logger.trace("patternString: " + patternString);
								logger.trace("filename: " + fileName);
							}
							matcher = patternCache.getMatcher(patternString + ".*",rec.isCaseSensitive(),
									new File(repo.getBaseSourcePath()).toURI().relativize(new File(fileName.getFile().getCanonicalPath()).toURI()).getPath());
							if (matcher.find()) {
								if (logger.isTraceEnabled())
									logger.trace("found filename " + fileName + " with group");

								key = "";
								int i = 0;
								for (i = 0; i < matcher.groupCount(); i++) {
										if (logger.isTraceEnabled())
											logger.trace("group matched : " + matcher.group(i));
										key += matcher.group(i + 1) + " ";
								}
								if (logger.isTraceEnabled())
									logger.trace("i : " + i + " nbRec: " + nbRec);
								if (i == nbRec) {
									if (!sourceFileGroup.containsKey(key)) {
										ArrayList<FileRecord> v = new ArrayList<FileRecord>();
										v.add(fileName);
										sourceFileGroup.put(key, v);
										if (logger.isTraceEnabled())
											logger.trace(" to key: " + key + " added : " + fileName);
									} else {
										sourceFileGroup.get(key).add(fileName);
										if (logger.isTraceEnabled())
											logger.trace(" to key: " + key + " added : " + fileName);

									}

								}
								/*
								 * if (tempV != null) { sourceFileGroup.put(key,
								 * tempV); logger.info("Added file " + fileName
								 * + " to group " + key.toString());
								 * logger.info("files " + tempV);
								 * 
								 * }
								 */
							}

						} catch (Exception e1) {
							e1.printStackTrace();
							// System.exit(1);
						}

						// logger.info("found group " + key + "with " +
						// groupedFiles.size() + " files in source " +
						// src.getSourceName());
						
						//option for ordering files by date of lines - useless at this point
						if (order)
							{sourceFileGroup.put(key,Tools.orderFiles(sourceFileGroup.get(key),src));
							} else{
								sourceFileGroup.put(key,sourceFileGroup.get(key));								
							}
					}

		return sourceFileGroup;
		}
else {return null;}
	}
	
	private static Map<Class,Map<Recording, String>> getAllRegexp(Repository repo, Source source) {
		Map<Class,Map<Recording, String>> recMatch = new HashMap<Class,Map<Recording, String>>();
		recMatch.put(StatRecording.class,getRegexp(repo,source,StatRecording.class));
		recMatch.put(EventRecording.class,getRegexp(repo,source,StatRecording.class));
		recMatch.put(ReportRecording.class,getRegexp(repo,source,StatRecording.class));
		return recMatch;
	}

	public static Map<Recording, String> getAllRegexSingleMap(Repository repo, Source source) {
		long startTime = System.currentTimeMillis();
		Map<Recording, String> recMatch = new HashMap<Recording, String>();
		if (Preferences.getBooleanPreference("gatherstats")){
			Map<Recording, String> g1= getRegexp(repo,source,StatRecording.class);
			if (g1!=null){
			recMatch.putAll(g1);
			}
		}
		if (Preferences.getBooleanPreference("gatherevents")){
			Map<Recording, String> g2= getRegexp(repo,source,EventRecording.class);
			if (g2!=null){
				recMatch.putAll(g2);	
			}
		}
		if (Preferences.getBooleanPreference("gatherreports")){
			Map<Recording, String> g3= getRegexp(repo,source,ReportRecording.class);
			if (g3!=null){
			recMatch.putAll(g3);
			}
		}
		estimatedTime = System.currentTimeMillis() - startTime;
		logger.debug("getAllRegexSingleMap time: " + estimatedTime);
		return recMatch;
	}
	
	
	private static Map<Recording, String> getRegexp(Repository repo, Source source, Class recordingClass) {
		Map<Recording, String> recMatch = new HashMap<Recording, String>();
		Map<Recording, Boolean> activeRecordingOnSourceCache = new HashMap<Recording, Boolean>();
		ArrayList<Recording> recordings;
		StringBuffer sb = new StringBuffer(200);
		recordings = repo.getRecordings(recordingClass,true);
		Iterator<Recording> recordingIterator = recordings.iterator();
		boolean forceSourceDateFormat = Preferences.getBooleanPreference("ForceSourceDateFormat");
		
		while (recordingIterator.hasNext()) {
			Recording rec = recordingIterator.next();
			if (!activeRecordingOnSourceCache.containsKey(rec)) {
				activeRecordingOnSourceCache.put(rec, source.isActiveRecordingOnSource(rec));
			}
			if (activeRecordingOnSourceCache.get(rec)) {
				if (rec.getIsActive() == true) {
					ArrayList<RecordingItem> recordingItem = ((Recording) rec).getRecordingItem();
					Iterator<RecordingItem> recItemIte = recordingItem.iterator();
					if (logger.isTraceEnabled()) {
						logger.trace("Record: " + rec.getName());
					}
					sb.setLength(0);
					// processing each line of the table
					while (recItemIte.hasNext()) {
						RecordingItem recItem = recItemIte.next();
						String stBefore = (String) recItem.getBefore();
						String stType = (String) recItem.getType();
						String stAfter = (String) recItem.getAfter();
						String stInside = recItem.getInside();
						sb.append(stBefore);
						sb.append("(");
						if (forceSourceDateFormat){
							sb.append(getMainRegex(stType,stInside,source.getDateFormat()));
						}else{
							sb.append(getMainRegex(stType,stInside,repo.getDateFormat(rec.getDateFormatID())));
						}
						sb.append(")");
						sb.append(stAfter);				
					}
						recMatch.put(rec, sb.toString());
					if (logger.isTraceEnabled()) {
						logger.trace("regexp: " +rec.getRegexp());
						logger.trace("Pattern: " + sb.toString());
					}
				}
			}
		}
		return recMatch;
	}

	public static String getMainRegex(String stType, String stInside, DateFormat dateFormat) {
		if (stType.equals("date")) {
		return dateFormat.getPattern();
		} else{
			if (!stType.equals("manual")){
				return (getTypeString(stType));
			} else {
				return (stInside);
			}}
	}

	// public static get
	public static String getTypeString(String type) {
		String typeString = "";
		switch (type) {
		case "integer":
			typeString = "\\d+";
			break;
		case "percent":
			typeString = "\\d+";
			break;
		case "word":
			typeString = "\\w+";
			break;
		case "stringminimum":
			typeString = ".*?";
			break;
		case "string":
			typeString = ".*";
			break;
		case "double":
			typeString = "[-+]?[0-9]*.?[0-9]+(?:[eE][-+]?[0-9]+)?";
			break;
		case "long": // keeping for compatibility with older templates
			typeString = "\\d+";
			break;
		/*
		 * case "date": typeString = repo.getDateFormat(rec.getDateFormatID());
		 * break;
		 */
		default:
			typeString = ".*";
			break;
		}
		return typeString;
	}
	
	public static ChartData gatherSourceData(final Repository repo, boolean order) {

		PatternCache patternCache = new PatternCache();
		ChartData cd = new ChartData();
		List<File> listOfFiles = null;
		logger.debug("Base file path: " + repo.getBaseSourcePath());
		if (repo.getBaseSourcePath() == null)
			return null;
		File folder = new File(repo.getBaseSourcePath());
		try {
			if (repo.isRecursiveMode()) {
				listOfFiles = FileListing.getFileListing(folder);
			} else {
				listOfFiles = Arrays.asList(folder.listFiles());

			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (listOfFiles != null)
			logger.debug("number of files: " + listOfFiles.size());
		cd.sourceArrayList = repo.getSources();
		Iterator<Source> sourceIterator = cd.sourceArrayList.iterator();

		while (sourceIterator.hasNext()) {
			final Source source = sourceIterator.next();
			cd.selectedSourceFiles = new HashMap<Integer, FileRecord>();
			// sourceFiles contains all the matched files for a given source
			if (source.getActive()) {
				for (int i = 0; i < listOfFiles.size(); i++) {
					if (listOfFiles.get(i).isFile()) {
						String s1 = source.getSourcePattern();
						try {
							Matcher matcher = patternCache.getMatcher(s1,true,
									new File(repo.getBaseSourcePath()).toURI().relativize(new File(listOfFiles.get(i).getCanonicalPath()).toURI()).getPath());

							if (logger.isTraceEnabled()) {
								logger.trace(i
										+ " matching file: "
										+ new File(repo.getBaseSourcePath()).toURI().relativize(new File(listOfFiles.get(i).getCanonicalPath()).toURI())
												.getPath() + " with pattern: " + s1);
							}

							if (matcher.find()) {

								FileRecord tempFileRecord = new FileRecord(i, new File(listOfFiles.get(i).getCanonicalPath()));
								cd.selectedSourceFiles.put(i, tempFileRecord);
								if (logger.isTraceEnabled()) {

									logger.trace("Source: " + source.getSourceName() + " file: " + listOfFiles.get(i).getCanonicalPath());
									logger.trace(" Graphpanel file: "
											+ new File(repo.getBaseSourcePath()).toURI().relativize(new File(listOfFiles.get(i).getCanonicalPath()).toURI())
													.getPath());
									logger.trace(tempFileRecord.getCompletePath());
								}

							}
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
				if (logger.isEnabledFor(Level.DEBUG))
					logger.debug("matched file: " + cd.selectedSourceFiles.size() + " to source  " + source.getSourceName());
			}
			cd.sourceFileArrayListMap.put(source, cd.selectedSourceFiles);
		}
		Map<String, ArrayList<FileRecord>> sourceFileGroup = null;
		Iterator<Entry<Source, Map<Integer, FileRecord>>> ite = cd.sourceFileArrayListMap.entrySet().iterator();
		while (ite.hasNext()) {
			final Map.Entry sourcePairs = ite.next();
			final Source src = (Source) sourcePairs.getKey();
			Map<Integer, FileRecord> sourceFiles = (Map<Integer, FileRecord>) sourcePairs.getValue();
			sourceFileGroup = getSourceFileGroup(sourceFiles, src, repo,order);
			if (sourceFileGroup!=null && sourceFileGroup.keySet().size()>0)
				logger.info("matched groups: " + (sourceFileGroup!=null? sourceFileGroup.keySet().size():"") + " for source " + src.getSourceName());
		//	logger.debug(sourceFileGroup.toString());
			cd.setGroupFilesArrayListMap(src, sourceFileGroup);
		}
		return cd;
	}

	public static void populateRecordingSamples(Repository repo) {
		PatternCache patternCache = new PatternCache();
		FileReader flstr = null;
		BufferedReader buf1st;
		Map<Recording, String> recMatch = new HashMap<Recording, String>();
		Matcher matcher;
		Matcher matcher2;
		if (repo.getBaseSourcePath() == null)
			return;
		File folder = new File(repo.getBaseSourcePath());
		try {
			if (repo.isRecursiveMode()) {
				listOfFiles = FileListing.getFileListing(folder);
			} else {
				listOfFiles = Arrays.asList(folder.listFiles());
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
		}
		if (repo != null && repo.getBaseSourcePath() != null) {
			ChartData cd = DataMiner.gatherSourceData(repo,false);
			ArrayList sources = repo.getSources();
			Iterator sourceArrayListIte = sources.iterator();
			while (sourceArrayListIte.hasNext()) {

				// Map<Recording, String> regMap=getRegexp(repo, src);
				cd.sourceArrayList = repo.getSources();
				Iterator<Source> sourceIterator = cd.sourceArrayList.iterator();

				Source src = (Source) sourceArrayListIte.next();
				Map<String, ArrayList<FileRecord>> hm = cd.getGroupFilesMap(src);
				logger.info("population");
				if (hm != null && hm.entrySet() != null) {
					Iterator it = hm.entrySet().iterator();
					while (it.hasNext()) {
						final Map.Entry pairs = (Map.Entry) it.next();
						logger.info("populating: " + pairs.getKey());
						ArrayList<FileRecord> grouFile = (ArrayList<FileRecord>) pairs.getValue();
						// return DataMiner.mine((String) pairs.getKey(),
						// (ArrayList<String>) pairs.getValue(), repo, source,
						// repo.isStats(), repo.isTimings());
						Iterator<FileRecord> fileArrayListIterator = grouFile.iterator();
						while (fileArrayListIterator.hasNext()) {
							final FileRecord fileName = fileArrayListIterator.next();
							try {
								flstr = new FileReader(new File(fileName.getCompletePath()));
							} catch (FileNotFoundException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}
							buf1st = new BufferedReader(flstr);
							String line;
							logger.info("matched file:" + fileName);
							recMatch = getAllRegexSingleMap(repo, src);
							try {
								while ((line = buf1st.readLine()) != null) {
									// check against one Recording pattern at a
									// tim
									// if (logger.isDebugEnabled()) {
									// logger.debug("line " + line);
									// }
									Iterator recMatchIte = recMatch.entrySet().iterator();
									while (recMatchIte.hasNext()) {
										Map.Entry me = (Map.Entry) recMatchIte.next();
										Recording rec = (Recording) me.getKey();
										matcher = patternCache.getMatcher((String) (rec.getRegexp()), rec.isCaseSensitive(),line);
										if (matcher.find()) {
											// logger.info("1**** matched: " +
											// line);
											ArrayList<RecordingItem> recordingItem = ((Recording) rec).getRecordingItem();
											int cnt = 0;
											matcher2 = patternCache.getMatcher((String) me.getValue(), rec.isCaseSensitive(),line);
											if (matcher2.find()) {

												DataVault.addMatchedLines(rec, line);
											} else {
												DataVault.addUnmatchedLines(rec, line);
											}
										}

									}
								}
							} catch (IOException e1) {
								// TODO Auto-generated catch block
								e1.printStackTrace();
							}
						}
					}
				}
			}
		}
	}

/*	public static ArrayList<Map> exportData(Repository repo) {
		gatherMineResultSet(null,repo, null);
		return null;

	}*/
	/*
	 * public static ArrayList<Map> exportData(Repository repo) { PatternCache
	 * patternCache = new PatternCache(); Matcher matcher = null; ArrayList<Map>
	 * expVec = new ArrayList<Map>(); File folder = new
	 * File(repo.getBaseSourcePath()); try { if (repo.isRecursiveMode()) {
	 * listOfFiles = FileListing.getFileListing(folder); } else { listOfFiles =
	 * Arrays.asList(folder.listFiles());
	 * 
	 * } } catch (FileNotFoundException e) { // TODO Auto-generated catch block
	 * e.printStackTrace(); } if (logger.isEnabledFor(Level.INFO))
	 * logger.info("number of files: " + listOfFiles.size()); // int[][]
	 * fileListMatches = new int[listOfFiles.size()][3];
	 * 
	 * Iterator sourceIterator = repo.getSources().iterator();
	 * 
	 * while (sourceIterator.hasNext()) { Source r = (Source)
	 * sourceIterator.next(); ArrayList<String> sourceFiles = new
	 * ArrayList<String>(); // sourceFiles contains all the matched files for a
	 * given source
	 * 
	 * if (r.getActive()) {
	 * 
	 * for (int i = 0; i < listOfFiles.size(); i++) { if
	 * (listOfFiles.get(i).isFile()) { // logger.info("File " + //
	 * listOfFiles.get(i).getName()); String s1 = r.getSourcePattern(); matcher
	 * = patternCache.getPattern(s1).matcher(listOfFiles.get(i).getName()); if
	 * (matcher.find()) { try { sourceFiles.add(new
	 * File(repo.getBaseSourcePath()).toURI().relativize(new
	 * File(listOfFiles.get(i).getCanonicalPath()).toURI()) .getPath());
	 * 
	 * //
	 * logger.info(" Graphpanel file1: "+listOfFiles.get(i).getCanonicalPath());
	 * // logger.info(" Graphpanel file: "+new //
	 * File(repo.getBaseSourcePath()).toURI() // .relativize(new //
	 * File(listOfFiles.get(i).getCanonicalPath()).toURI()).getPath()); } catch
	 * (IOException e) { // TODO Auto-generated catch block e.printStackTrace();
	 * } // sourceFiles.add(listOfFiles.get(i).getAbsolutePath() // +
	 * listOfFiles.get(i).getName()); } } } logger.info("matched file: " +
	 * sourceFiles.size() + " to source group " + r.getSourceName()); }
	 * Map<String, ArrayList<String>> sourceFileGroup =
	 * getSourceFileGroup(sourceFiles, r, repo); expVec.add(sourceFileGroup);
	 * logger.info("matched groups: " + sourceFileGroup.keySet().size() +
	 * " for source " + r.getSourceName()); Iterator it =
	 * sourceFileGroup.entrySet().iterator(); while (it.hasNext()) { Map.Entry
	 * pairs = (Map.Entry) it.next(); logger.info(pairs.getKey().toString() +
	 * " = " + pairs.getValue()); // it.remove(); // avoids a
	 * ConcurrentModificationException
	 * 
	 * FileMineResultSet fMR = fastMine((ArrayList<String>) pairs.getValue(),
	 * repo, r, false, false);
	 * 
	 * expVec.add(fMR.eventGroupTimeSeries);
	 * expVec.add(fMR.statGroupTimeSeries); } } return expVec; }
	 */
} public class Persister {
	private static Logger logger = Logger.getLogger(Persister.class.getName());
	static XStream xstream = new XStream(new StaxDriver());

	public static void save(File file, Object object) {

		FileOutputStream fos = null;
		try {
			String xml = xstream.toXML(object);
			fos = new FileOutputStream(file);
			// fos.write("<?xml version=\"1.0\"?>".getBytes("UTF-8"));
			byte[] bytes = xml.getBytes("UTF-8");
			fos.write(bytes);

		} catch (Exception e) {
			logger.info("Error in XML Write: " + e.getMessage());
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static Object open(File file) {
		XStream xstream = new XStream(new StaxDriver());
		FileOutputStream fos = null;
		Object returnedObject = null;
		try {
			returnedObject = (Object) xstream.fromXML(file);
			/*
			 * fos = new FileOutputStream(file);
			 * 
			 * byte[] bytes = xml.getBytes("UTF-8"); fos.write(bytes);
			 */

		} catch (Exception e) {
			logger.info("No existing preference file: " + e.getMessage());
		} finally {
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return returnedObject;
	}

	public Persister() {

	}

} public class Tools {
	private static Logger logger = Logger.getLogger(Tools.class.getName());

	public Tools() {
		// TODO Auto-generated constructor stub
	}

	public static boolean generateFlatFiles(Repository repo, File folderLocation) {

		// PatternCache patternCache = new PatternCache();
		FileReader flstr = null;
		BufferedReader buf1st = null;
		Map<Recording, String> recMatch = new HashMap<Recording, String>();
		Matcher matcher;
		Matcher matcher2;
		BufferedWriter bufWriter = null;
		if (repo.getBaseSourcePath() == null)
			return false;
		File folder = new File(repo.getBaseSourcePath());
		if (repo != null && repo.getBaseSourcePath() != null) {
			ChartData cd = DataMiner.gatherSourceData(repo, true);
			ArrayList sources = repo.getSources();
			Iterator sourceArrayListIte = sources.iterator();
			while (sourceArrayListIte.hasNext()) {
				cd.sourceArrayList = repo.getSources();
				Iterator<Source> sourceIterator = cd.sourceArrayList.iterator();
				Source src = (Source) sourceArrayListIte.next();
				Map<String, ArrayList<FileRecord>> hm = cd.getGroupFilesMap(src);
				logger.info("Source: " + src.getSourceName());
				if (hm != null && hm.entrySet() != null) {
					Iterator it = hm.entrySet().iterator();
					while (it.hasNext()) {
						final Map.Entry pairs = (Map.Entry) it.next();
						// removing file separators so that files are stored
						// inside one folder and to prevent no such directory
						// error
						logger.info("original file string: " + pairs.getKey().toString());
						String noSeparatorString = pairs.getKey().toString().replace("/", "-");
						logger.info("updated file string: " + noSeparatorString);
						File oneFile = new File(folderLocation.getAbsolutePath() + File.separator + noSeparatorString);
						logger.info("complete file string: " + oneFile.getAbsolutePath());
						FileWriter fileWriter = null;
						try {
							fileWriter = new FileWriter(oneFile);
						} catch (IOException e2) {
							// TODO Auto-generated catch block
							e2.printStackTrace();
						}
						if (fileWriter != null) {
							bufWriter = new BufferedWriter(fileWriter);
							logger.info("Source group: " + pairs.getKey());
							ArrayList<FileRecord> grouFile = (ArrayList<FileRecord>) pairs.getValue();
							// return DataMiner.mine((String) pairs.getKey(),
							// (ArrayList<String>) pairs.getValue(), repo,
							// source,
							// repo.isStats(), repo.isTimings());
							Iterator<FileRecord> fileArrayListIterator = grouFile.iterator();
							while (fileArrayListIterator.hasNext()) {
								final FileRecord fileName = fileArrayListIterator.next();
								try {
									flstr = new FileReader(new File(fileName.getCompletePath()));
								} catch (FileNotFoundException e1) {
									// TODO Auto-generated catch block
									e1.printStackTrace();
								}
								if (flstr != null) {
									buf1st = new BufferedReader(flstr);
									String line;
									logger.info("wrote file:" + fileName.getCompletePath());
									// try {
									try {
										while ((line = buf1st.readLine()) != null) {
											bufWriter.write(line);
											bufWriter.newLine();
										}
									} catch (IOException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
									}
								}
								
								try {
									buf1st.close();
								} catch (IOException e) {
									// TODO Auto-generated catch block
									e.printStackTrace();
								}
							}
						}
						try {
							bufWriter.close();
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						
					}
				}
			}

		}
		return true;

	}

	// ordering files by date of lines
	public static ArrayList<FileRecord> orderFiles(ArrayList<FileRecord> groupfiles, Source src) {
		// String test = Preferences.getPreference("ThreadPool_fileOrder");
		FileReader flstr = null;
		BufferedReader buf1st = null;
		Map<Date, FileRecord> tempDateFile = new HashMap<Date, FileRecord>();
		ArrayList<FileRecord> finaList = new ArrayList<FileRecord>();
		DateFormat df = src.getDateFormat();
		if (df != null) {
			Pattern srcDatePattern = Pattern.compile(df.getPattern() + ".*");
			logger.debug(df.getPattern());
			java.text.DateFormat fastDateFormat = ThreadLocalDateFormatMap.getInstance().createSimpleDateFormat(df.getDateFormat());
			if (groupfiles != null) {
				if (df.getDateFormat() != "") {
					for (FileRecord fileRecord : groupfiles) {
						try {
							if (logger.isDebugEnabled()) {
								logger.debug("looking for first date in file: " + (String) fileRecord.getCompletePath().toString());
							}
							flstr = new FileReader(fileRecord.getCompletePath());
						} catch (FileNotFoundException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						buf1st = new BufferedReader(flstr);
						String line;
						int lineCount = 0;
						try {
							// recMatch = getRegexp(repo, source);
							// checking lines until a date is found
							while ((line = buf1st.readLine()) != null && lineCount < 1000) {
								Matcher matcher = srcDatePattern.matcher(line);
								if (matcher.find()) { // date found, now parsing
														// to date
									try {
										Date date1 = fastDateFormat.parse(matcher.group(0));
										tempDateFile.put(date1, fileRecord);
										break;
									} catch (ParseException e) {
										// TODO Auto-generated catch block
										e.printStackTrace();
										logger.info(df.getPattern());
									}
								}
							}
						} catch (IOException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
						} finally {
							try {
								buf1st.close();
							} catch (IOException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
						}

					}
				} else {
					return groupfiles;
				}
			}

			Iterator<Date> ite = tempDateFile.keySet().iterator();

			while (ite.hasNext()) {
				Date date = (Date) ite.next();
				logger.debug("BEFORE ORDERING - date: " + date + "File: " + ((FileRecord) tempDateFile.get(date)).getCompletePath());

			}
			List<Date> test1 = new ArrayList<Date>();

			// sorting list of dates
			test1.addAll(tempDateFile.keySet());
			Collections.sort(test1, new Comparator<Date>() {
				public int compare(Date o1, Date o2) {
					return Long.compare(o1.getTime(), o2.getTime());
				}
			});
			Iterator<Date> ite2 = test1.iterator();

			while (ite2.hasNext()) {
				Date date = (Date) ite2.next();
				finaList.add(tempDateFile.get(date));
				logger.debug("ORDERED - date: " + date + "File: " + ((FileRecord) tempDateFile.get(date)).getCompletePath());

			}

			return finaList;
		} else
			return groupfiles;

	}

}
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.FlowLayout;
import javax.swing.JCheckBox;
import javax.swing.JSeparator;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JButton;
import javax.swing.JTree;
import javax.swing.SpinnerDateModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.Color;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import logdruid.data.Preferences;
import logdruid.data.Repository;
import logdruid.data.Source;
import logdruid.data.mine.ChartData;
import logdruid.data.mine.DataVault;
import logdruid.engine.Miner;
import logdruid.ui.chart.GraphPanel;
import logdruid.ui.dialog.FileChooserDialog;
import logdruid.ui.dialog.FileSaverDialog;
import logdruid.ui.editor.DateEditor;
import logdruid.ui.mainpanel.EventRecordingSelectorPanel;
import logdruid.ui.mainpanel.MetadataRecordingSelectorPanel;
import logdruid.ui.mainpanel.PreferencePanel;
import logdruid.ui.mainpanel.RecordingList;
import logdruid.ui.mainpanel.ReportPanel;
import logdruid.ui.mainpanel.ReportRecordingSelectorPanel;
import logdruid.ui.mainpanel.SourceInfoPanel;
import logdruid.ui.mainpanel.SourcePanel;
import logdruid.ui.mainpanel.StatRecordingSelectorPanel;
import logdruid.util.DataMiner;
import logdruid.util.Persister;
import logdruid.util.Tools;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import org.apache.log4j.Logger;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.io.File;
import java.util.Date;
import java.util.Iterator;
import java.util.ArrayList;
import java.awt.Font;
import javax.swing.JProgressBar;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.BoxLayout;
import java.awt.Insets;
    }
    
    public void setValueNow(final int j) {
    		progressBar.setValue(j);
              /*  logger.info("setValueNow " + j);
                StackTraceElement[] elements = Thread.currentThread().getStackTrace();

                for(int i=0; i<elements.length; i++) {
                	logger.debug(elements[i]);
                }*/
                
    }
    
    public void progress() {
    	 SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
                updateProgress2();
             }
             });
    }
    
    
	public void updateTreeSources(ArrayList<Source> sources) {
		TreePath initialTreePath = tree.getSelectionPath();
		DefaultMutableTreeNode DMTNsources_child;
		DMTnode_sources.removeAllChildren();
		// ((DefaultTreeModel)tree.getModel()).reload();
		for (int i = 0; i < sources.size(); i++) {
			if (((Source) sources.get(i)).getActive()) {
				String name = ((Source) sources.get(i)).getSourceName();
				DMTNsources_child = new DefaultMutableTreeNode(name);
				DMTNsources_child.add(new DefaultMutableTreeNode("<html>File Grouping</html>"));
				DMTNsources_child.add(new DefaultMutableTreeNode("<html>Stats</html>"));
				DMTNsources_child.add(new DefaultMutableTreeNode("<html>Events</html>"));
				DMTNsources_child.add(new DefaultMutableTreeNode("<html>Reports</html>"));
				DMTnode_sources.add(DMTNsources_child);
				DMTnode_sources.getParent();
			}
		}

		// DMTnode_sources.
		// ((DefaultTreeModel)tree.getModel()).reload();
		// ((DefaultTreeModel)tree.getModel()).nodeStructureChanged(DMTnode_sources.getPath());
		TreeNode[] t = DMTnode_sources.getPath();
		((DefaultTreeModel) tree.getModel()).nodeStructureChanged(t[(t.length - 1)]);
		tree.setSelectionPath(initialTreePath);
		tree.expandPath(initialTreePath);
		// tree.fireTreeExpanded(initialTreePath);
		tree.revalidate();
		tree.repaint();
	}

	private void treeSelected() {
		DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
		if (node != null) {
			logger.debug(node.toString());
			treeSelected = node.toString();
			if (treeSelected.equals("<html><font size=3>Sources</font></html>")) {
				panel_1.removeAll();
				panel_1.add(new SourcePanel(repository, thiis));
				panel_1.revalidate();
			} else if (treeSelected.equals("Recordings")) {
				panel_1.removeAll();
				panel_1.add(new RecordingList(repository));
				panel_1.revalidate();
			} else if (treeSelected.equals("Preferences")) {
				panel_1.removeAll();
				panel_1.add(new PreferencePanel(repository));
				panel_1.revalidate();
			} else if (treeSelected.equals("<html>Stats</html>")) {
				panel_1.removeAll();
				panel_1.add(new StatRecordingSelectorPanel(repository, (Source) repository.getSource(node.getParent().toString())));
				panel_1.revalidate();
			} else if (treeSelected.equals("<html>Events</html>")) {
				panel_1.removeAll();
				panel_1.add(new EventRecordingSelectorPanel(repository, (Source) repository.getSource(node.getParent().toString())));
				panel_1.revalidate();
			} else if (treeSelected.equals("<html>Reports</html>")) {
				panel_1.removeAll();
				panel_1.add(new ReportRecordingSelectorPanel(repository, (Source) repository.getSource(node.getParent().toString())));
				panel_1.revalidate();
			} else if (treeSelected.equals("<html><font color=\"blue\" size=3>Report</font></html>")) {

				Thread t =new Thread()
		        {
		            public void run() {
						if (working==false){
		            	working=true;
		            	try {
						logger.debug("Reports panel loading ");				
						if (DataVault.getMineResultSet() == null) {							
						thiis.setValueNow(0);
						progressBarValue=0;	
						cd = DataMiner.gatherSourceData(repository,false);
						DataVault.setMineResultSet(Miner.gatherMineResultSet(cd,repository,thiis));
						logger.info("gathering source data");
		            	thiis.setValueNow(progressBarValue);
						}
						if (reportPanel == null) {
							logger.info(" new graph Panel");
							//cd = DataMiner.gatherSourceData(repository);
							reportPanel = new ReportPanel(repository, DataVault.getMineResultSet());
						}
						panel_1.removeAll();
						panel_1.add(reportPanel);
						panel_1.validate();
						panel_1.repaint();
						logger.debug("Report panel loaded ");
		            	} catch (Exception e){
							logger.error("exception: ", e);
							working=false;
						}
						working=false;
		            }
		            }};
		        t.start();
				
			} else if (treeSelected.equals("<html>File Grouping</html>")) {
				panel_1.removeAll();
				panel_1.add(new MetadataRecordingSelectorPanel(repository, (Source) repository.getSource(node.getParent().toString())));