[med-svn] [tn-seqexplorer] 01/02: New upstream version 0.0+20151207

Andreas Tille tille at debian.org
Fri May 5 19:22:55 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository tn-seqexplorer.

commit e200a8f79f3f83a65df46a7dbbe95c971a91c9c0
Author: Andreas Tille <tille at debian.org>
Date:   Fri May 5 21:12:55 2017 +0200

    New upstream version 0.0+20151207
---
 .classpath                                         |   18 +
 .project                                           |   17 +
 Documents/Readme.docx                              |  Bin 0 -> 35762 bytes
 Documents/Tn-seq_Explorer1.5_User_Guide.pdf        |  Bin 0 -> 608083 bytes
 src/CompareUtilities/Compare.java                  |  490 +++
 src/CompareUtilities/CompareMain.java              |   40 +
 src/CompareUtilities/InspouDistance.java           |  666 ++++
 src/CompareUtilities/Utilities.java                |   64 +
 src/CustomGUIComponent/BoldCellRenderer.java       |   19 +
 src/CustomGUIComponent/FolderChooser.java          |   57 +
 src/CustomGUIComponent/IntegerInputVerifier.java   |   43 +
 src/CustomGUIComponent/MyChartMouseListener.java   |   37 +
 src/CustomGUIComponent/MyXYDataItem.java           |   26 +
 .../PercentageInputVerifier.java                   |   53 +
 src/GUI/AboutFrame.java                            |   38 +
 src/GUI/AddMoreIndices.java                        | 1355 +++++++
 src/GUI/ExtendedPlotViewer.java                    |  306 ++
 src/GUI/LegalDisclaimer.java                       |   72 +
 src/GUI/MainFrame.java                             | 4050 ++++++++++++++++++++
 src/GUI/PlotViewer.java                            |  210 +
 src/GUI/ProgressBarUpdater.java                    |   40 +
 src/GUI/RemoteInstall.java                         |  303 ++
 src/GUI/SelectFNA.java                             |  414 ++
 src/GUI/Utilities.java                             |   96 +
 src/GUI/WorkspaceChooser.java                      |  406 ++
 src/UtilityFunctions/FilterTable.java              |  125 +
 src/essgenes/AddColumns.java                       | 1036 +++++
 src/essgenes/ImgFileInfo.java                      |   12 +
 src/essgenes/Main.java                             |   48 +
 src/essgenes/Messages.java                         |   15 +
 src/essgenes/MyFileUtil.java                       |   86 +
 src/essgenes/PlotData.java                         |  592 +++
 src/essgenes/PrepareFiles.java                     |  899 +++++
 src/essgenes/ProjectInfo.java                      |   47 +
 src/essgenes/StatisticsHelper.java                 |  450 +++
 src/log4j.properties                               |   31 +
 src/resources/bowtie-bin/linux/bowtie2             |  583 +++
 src/resources/bowtie-bin/linux/bowtie2-align-l     |  Bin 0 -> 11241470 bytes
 src/resources/bowtie-bin/linux/bowtie2-align-s     |  Bin 0 -> 11227955 bytes
 src/resources/bowtie-bin/linux/bowtie2-build       |   98 +
 src/resources/bowtie-bin/linux/bowtie2-build-l     |  Bin 0 -> 3400174 bytes
 src/resources/bowtie-bin/linux/bowtie2-build-s     |  Bin 0 -> 3420470 bytes
 src/resources/bowtie-bin/mac/bowtie2               |  583 +++
 src/resources/bowtie-bin/mac/bowtie2-align-l       |  Bin 0 -> 1113520 bytes
 src/resources/bowtie-bin/mac/bowtie2-align-s       |  Bin 0 -> 1109448 bytes
 src/resources/bowtie-bin/mac/bowtie2-build         |   98 +
 src/resources/bowtie-bin/mac/bowtie2-build-l       |  Bin 0 -> 374916 bytes
 src/resources/bowtie-bin/mac/bowtie2-build-s       |  Bin 0 -> 370340 bytes
 .../bowtie-bin/win-64/bowtie2-align-s.exe          |  Bin 0 -> 31967831 bytes
 .../bowtie-bin/win-64/bowtie2-build-s.exe          |  Bin 0 -> 11328963 bytes
 src/resources/bwa-0.7.5a.tar.bz2                   |  Bin 0 -> 149887 bytes
 src/resources/done.gif                             |  Bin 0 -> 534 bytes
 src/resources/info.png                             |  Bin 0 -> 7795 bytes
 src/resources/install-bwa-redhat.sh                |   36 +
 src/resources/install-bwa-ubuntu.sh                |   38 +
 src/resources/legaldisclaimer.png                  |  Bin 0 -> 8863 bytes
 src/resources/load.gif                             |  Bin 0 -> 1849 bytes
 57 files changed, 13597 insertions(+)

diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..ea3d15b
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry excluding="log4j/" kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="lib/commons-net-3.3.jar"/>
+	<classpathentry kind="lib" path="lib/externalsortinginjava-0.1.7.jar"/>
+	<classpathentry kind="lib" path="lib/jcommon-1.0.20.jar"/>
+	<classpathentry kind="lib" path="lib/jfreechart-1.0.16.jar"/>
+	<classpathentry kind="lib" path="lib/log4j-1.2.17.jar"/>
+	<classpathentry kind="lib" path="lib/poi-3.9-20121203.jar"/>
+	<classpathentry kind="lib" path="lib/commons-io-2.4.jar"/>
+	<classpathentry kind="lib" path="lib/jtstand-desktop-1.2.1.jar"/>
+	<classpathentry kind="lib" path="lib/guava-16.0.1.jar"/>
+	<classpathentry kind="lib" path="lib/commons-math3-3.2-javadoc.jar"/>
+	<classpathentry kind="lib" path="lib/commons-math3-3.2.jar"/>
+	<classpathentry kind="lib" path="forms-1.3.0.jar" sourcepath="forms-1.3.0-src.zip"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/.project b/.project
new file mode 100644
index 0000000..7196036
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>EssentialGenes</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>		
+			<name>org.eclipse.jdt.core.javabuilder</name>		
+				<arguments>		
+				</arguments>		
+			</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/Documents/Readme.docx b/Documents/Readme.docx
new file mode 100644
index 0000000..79163a8
Binary files /dev/null and b/Documents/Readme.docx differ
diff --git a/Documents/Tn-seq_Explorer1.5_User_Guide.pdf b/Documents/Tn-seq_Explorer1.5_User_Guide.pdf
new file mode 100644
index 0000000..0de5a94
Binary files /dev/null and b/Documents/Tn-seq_Explorer1.5_User_Guide.pdf differ
diff --git a/src/CompareUtilities/Compare.java b/src/CompareUtilities/Compare.java
new file mode 100644
index 0000000..15b6d10
--- /dev/null
+++ b/src/CompareUtilities/Compare.java
@@ -0,0 +1,490 @@
+package CompareUtilities;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+
+import org.apache.log4j.Logger;
+
+import com.jgoodies.forms.factories.FormFactory;
+import com.jgoodies.forms.layout.ColumnSpec;
+import com.jgoodies.forms.layout.FormLayout;
+import com.jgoodies.forms.layout.RowSpec;
+
+public class Compare extends JFrame {
+
+	/**
+	 * 
+	 */
+	private Logger logger = Logger.getLogger(Compare.class.getName());
+	private static final long serialVersionUID = -2458273832974069254L;
+	private JPanel contentPane;
+	private JTextField input1Txt;
+	private JTextField header1Txt;
+	private JTextField position1Txt;
+	private JTextField gene1Txt;
+	private JTextField index1Txt;
+	private JLabel lblInputDataSet_1;
+	private JTextField input2Txt;
+	private JLabel lblHeaderSkipLines_1;
+	private JTextField header2Txt;
+	private JButton input1Btn;
+	private JButton input2Btn;
+	private JLabel lblPositionColumns_1;
+	private JLabel lblGeneNameColumns;
+	private JLabel lblEssentialityIndexColumn_1;
+	private JTextField position2Txt;
+	private JTextField gene2Txt;
+	private JTextField index2Txt;
+	private JLabel lblOutputFolder;
+	private JTextField outputTxt;
+	private JButton outputBtn;
+	private JButton processBtn;
+	private JCheckBox normalizeChk;
+	private JLabel lblOtheColumns;
+	private JTextField otherColumnsTxt;
+	private JLabel lblOtherColumns;
+	private JTextField otherColumns2Txt;
+
+	/**
+	 * Create the frame.
+	 */
+	public Compare() {
+		setResizable(false);
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		setBounds(100, 100, 667, 492);
+		contentPane = new JPanel();
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		setContentPane(contentPane);
+		contentPane.setLayout(new FormLayout(new ColumnSpec[] {
+				FormFactory.RELATED_GAP_COLSPEC,
+				ColumnSpec.decode("max(87dlu;default)"),
+				FormFactory.RELATED_GAP_COLSPEC,
+				ColumnSpec.decode("default:grow"),
+				FormFactory.RELATED_GAP_COLSPEC,
+				FormFactory.DEFAULT_COLSPEC,},
+			new RowSpec[] {
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,}));
+		
+		JLabel lblInputDataSet = new JLabel("Input data set one");
+		contentPane.add(lblInputDataSet, "2, 2, left, default");
+		
+		input1Txt = new JTextField();
+		input1Txt.setText("C:\\Users\\sina\\Desktop\\Essential Genes\\data\\Compare\\table 550.table.xls");
+		contentPane.add(input1Txt, "4, 2, fill, default");
+		input1Txt.setColumns(10);
+		
+		input1Btn = new JButton("Browse");
+		input1Btn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				Utilities.browseForInputFile(input1Txt, "xls", "Any text file with any format", Compare.this);
+			}
+		});
+		contentPane.add(input1Btn, "6, 2");
+		
+		JLabel lblHeaderSkipLines = new JLabel("Header skip lines");
+		contentPane.add(lblHeaderSkipLines, "2, 4, left, default");
+		
+		header1Txt = new JTextField();
+		header1Txt.setText("5");
+		contentPane.add(header1Txt, "4, 4, fill, default");
+		header1Txt.setColumns(10);
+		
+		JLabel lblPositionColumns = new JLabel("Position columns");
+		contentPane.add(lblPositionColumns, "2, 6, left, default");
+		
+		position1Txt = new JTextField();
+		position1Txt.setText("0 1");
+		contentPane.add(position1Txt, "4, 6, fill, default");
+		position1Txt.setColumns(10);
+		
+		JLabel lblGeneNameColumn = new JLabel("Locus tag column");
+		contentPane.add(lblGeneNameColumn, "2, 8, left, default");
+		
+		gene1Txt = new JTextField();
+		gene1Txt.setText("5");
+		contentPane.add(gene1Txt, "4, 8, fill, default");
+		gene1Txt.setColumns(10);
+		
+		JLabel lblEssentialityIndexColumn = new JLabel("Essentiality index column");
+		contentPane.add(lblEssentialityIndexColumn, "2, 10, left, default");
+		
+		index1Txt = new JTextField();
+		index1Txt.setText("8");
+		contentPane.add(index1Txt, "4, 10, fill, default");
+		index1Txt.setColumns(10);
+		
+		lblOtheColumns = new JLabel("Othe columns");
+		contentPane.add(lblOtheColumns, "2, 12");
+		
+		otherColumnsTxt = new JTextField();
+		otherColumnsTxt.setText("3 6 7");
+		contentPane.add(otherColumnsTxt, "4, 12, fill, default");
+		otherColumnsTxt.setColumns(10);
+		
+		lblInputDataSet_1 = new JLabel("Input data set two");
+		contentPane.add(lblInputDataSet_1, "2, 16, left, default");
+		
+		input2Txt = new JTextField();
+		input2Txt.setText("C:\\Users\\sina\\Desktop\\Essential Genes\\data\\Compare\\essentialgenes_alloutputmerged.tsv");
+		contentPane.add(input2Txt, "4, 16, fill, default");
+		input2Txt.setColumns(10);
+		
+		input2Btn = new JButton("Browse");
+		input2Btn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				Utilities.browseForInputFile(input2Txt, "tsv", "Any text file with any format", Compare.this);
+			}
+		});
+		contentPane.add(input2Btn, "6, 16");
+		
+		lblHeaderSkipLines_1 = new JLabel("Header skip lines");
+		contentPane.add(lblHeaderSkipLines_1, "2, 18, left, default");
+		
+		header2Txt = new JTextField();
+		header2Txt.setText("1");
+		contentPane.add(header2Txt, "4, 18, fill, default");
+		header2Txt.setColumns(10);
+		
+		lblPositionColumns_1 = new JLabel("Position columns");
+		contentPane.add(lblPositionColumns_1, "2, 20, left, default");
+		
+		position2Txt = new JTextField();
+		position2Txt.setText("10 11");
+		contentPane.add(position2Txt, "4, 20, fill, default");
+		position2Txt.setColumns(10);
+		
+		lblGeneNameColumns = new JLabel("Locus tag column");
+		contentPane.add(lblGeneNameColumns, "2, 22, left, default");
+		
+		gene2Txt = new JTextField();
+		gene2Txt.setText("1");
+		contentPane.add(gene2Txt, "4, 22, fill, default");
+		gene2Txt.setColumns(10);
+		
+		lblEssentialityIndexColumn_1 = new JLabel("Essentiality index column");
+		contentPane.add(lblEssentialityIndexColumn_1, "2, 24, left, default");
+		
+		index2Txt = new JTextField();
+		index2Txt.setText("7");
+		contentPane.add(index2Txt, "4, 24, fill, default");
+		index2Txt.setColumns(10);
+		
+		lblOtherColumns = new JLabel("Other Columns");
+		contentPane.add(lblOtherColumns, "2, 26, left, default");
+		
+		otherColumns2Txt = new JTextField();
+		otherColumns2Txt.setText("8");
+		contentPane.add(otherColumns2Txt, "4, 26, fill, default");
+		otherColumns2Txt.setColumns(10);
+		
+		lblOutputFolder = new JLabel("Output folder");
+		contentPane.add(lblOutputFolder, "2, 30, left, default");
+		
+		outputTxt = new JTextField();
+		contentPane.add(outputTxt, "4, 30, fill, default");
+		outputTxt.setColumns(10);
+		
+		outputBtn = new JButton("Browse");
+		outputBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				if (CompareMain.DEBUG){
+					outputTxt.setText("C:\\Users\\Sina\\Desktop\\" + "results" + System.currentTimeMillis() 
+							+ File.separator);
+				}else{
+					outputTxt.setText(Utilities.browseForFolder(Compare.this) + "results" + System.currentTimeMillis() 
+							+ File.separator);
+				}
+			}
+		});
+		contentPane.add(outputBtn, "6, 30");
+		
+		processBtn = new JButton("Process");
+		processBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				try {
+					startTheProcess();
+				} catch (IOException e1) {
+					logger.error(e1.getStackTrace());
+				}
+			}
+		});
+		
+		normalizeChk = new JCheckBox("Normalize");
+		contentPane.add(normalizeChk, "4, 34, right, default");
+		contentPane.add(processBtn, "6, 34");
+		
+		this.setLocationRelativeTo(null);
+	}
+
+	private void startTheProcess() throws IOException{
+		
+		File input1 = new File(input1Txt.getText());
+		File input2 = new File(input2Txt.getText());
+		
+		int headerSkip = Integer.parseInt(header1Txt.getText());
+		int geneIndex = Integer.parseInt(gene1Txt.getText());
+		int essentiality = Integer.parseInt(index1Txt.getText());
+		
+		String[] positionsString = position1Txt.getText().split(" ");
+		List<Integer> positions = new ArrayList<Integer>();
+		for (String pos : positionsString){
+			positions.add(Integer.parseInt(pos));
+		}
+		
+		String[] otherString = otherColumnsTxt.getText().split(" ");
+		List<Integer> others = new ArrayList<Integer>();
+		for (String other : otherString){
+			others.add(Integer.parseInt(other));
+		}
+		
+		BufferedReader br = new BufferedReader(new FileReader(input1));
+		for (int i = 0; i < headerSkip; i++){
+			br.readLine();
+		}
+		
+		List<GeneHolder> genes1 = new ArrayList<GeneHolder>();
+		
+		String line = "";
+		line = br.readLine();
+		while (line != null){
+			String[] temp = line.split("\t");
+			
+			GeneHolder gene = new GeneHolder();
+			gene.setStart(Integer.parseInt(temp[positions.get(0)]));
+			gene.setEnd(Integer.parseInt(temp[positions.get(1)]));
+			gene.setEssentialityIndex(Double.parseDouble(temp[essentiality]));
+			gene.setLocus_tag(temp[geneIndex]);
+			gene.setLength(Integer.parseInt(temp[others.get(0)]));
+			gene.setGene_symbol(temp[others.get(1)]);
+			gene.setDescription(temp[others.get(2)]);
+			genes1.add(gene);		
+			
+			line = br.readLine();
+		}
+		br.close();
+		
+		headerSkip = Integer.parseInt(header2Txt.getText());
+		geneIndex = Integer.parseInt(gene2Txt.getText());
+		essentiality = Integer.parseInt(index2Txt.getText());
+		
+		positionsString = position2Txt.getText().split(" ");
+		positions = new ArrayList<Integer>();
+		for (String pos : positionsString){
+			positions.add(Integer.parseInt(pos));
+		}
+		
+		br = new BufferedReader(new FileReader(input2));
+		for (int i = 0; i < headerSkip; i++){
+			br.readLine();
+		}
+		
+		otherString = otherColumns2Txt.getText().split(" ");
+		others = new ArrayList<Integer>();
+		for (String other : otherString){
+			others.add(Integer.parseInt(other));
+		}
+		
+		List<GeneHolder> genes2 = new ArrayList<GeneHolder>();
+		
+		line = br.readLine();
+		while (line != null){
+			String[] temp = line.split("\t");
+			
+			GeneHolder gene = new GeneHolder();
+			gene.setStart(Integer.parseInt(temp[positions.get(0)]));
+			gene.setEnd(Integer.parseInt(temp[positions.get(1)]));
+			if (temp[essentiality].equals("NA")){
+				gene.setEssentialityIndex(Double.NaN);
+			}else{
+				gene.setEssentialityIndex(Double.parseDouble(temp[essentiality]));
+			}
+			gene.setpValue(temp[others.get(0)]);
+			gene.setLocus_tag(temp[geneIndex]);
+			genes2.add(gene);	
+			
+			line = br.readLine();
+		}
+		br.close();
+		
+		if (normalizeChk.isSelected()){
+			
+			double sum = 0;
+			for (GeneHolder gene : genes1){
+				if (!gene.getEssentialityIndex().equals(Double.NaN)){
+					sum += gene.getEssentialityIndex();
+				}
+			}
+			
+			for (GeneHolder gene : genes1){
+				gene.setEssentialityIndex(gene.getEssentialityIndex() / sum);
+			}
+			
+			sum = 0;
+			for (GeneHolder gene : genes2){
+				if (!gene.getEssentialityIndex().equals(Double.NaN)){
+					sum += gene.getEssentialityIndex();
+				}
+			}
+			
+			for (GeneHolder gene : genes2){
+				gene.setEssentialityIndex(gene.getEssentialityIndex() / sum);
+			}
+		}
+		
+		File outputFolder = new File(outputTxt.getText());
+		if (!outputFolder.exists()){
+			outputFolder.mkdir();
+		}
+		
+		File output = new File(outputTxt.getText() + "compare_results.xls");
+		output.createNewFile();
+		
+		BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+		bw.write("Start\tEnd\tLength\tLocus_Tag\tGene_symbol\tDescription\tMiddle\tEI\tlogFC\tPValue\n");
+		for (int i = 0; i < genes1.size(); i++){
+
+			int j = 0;
+			for (j = 0; j < genes2.size(); j++){
+				if (genes2.get(j).getStart() == genes1.get(i).getStart() 
+						&& genes2.get(j).getEnd() == genes1.get(i).getEnd()){
+					break;
+				}
+			}
+			
+			StringBuilder toWrite = new StringBuilder();
+			toWrite.append(String.format("%d\t%d\t", genes1.get(i).getStart(), genes1.get(i).getEnd()));
+			toWrite.append(String.format("%d\t", genes1.get(i).getLength()));
+			toWrite.append(String.format("%s\t", genes1.get(i).getLocus_tag()));
+			toWrite.append(String.format("%s\t", genes1.get(i).getGene_symbol()));
+			toWrite.append(String.format("%s\t", genes1.get(i).getDescription()));
+			toWrite.append(String.format("%d\t", (genes1.get(i).getStart() + genes1.get(i).getEnd()) / 2));
+			
+			//NumberFormat formatter = new DecimalFormat("0.##E0");
+			toWrite.append(String.format("%s\t", genes1.get(i).getEssentialityIndex()));
+			
+			if (genes2.get(j).getEssentialityIndex().equals(Double.NaN)){
+				toWrite.append("0");				
+			}else{
+				
+				toWrite.append(String.format("%s\t", genes2.get(j).getEssentialityIndex()));
+			}
+			toWrite.append(String.format("%s", genes2.get(j).getpValue()));
+			bw.write(toWrite + "\n");
+		}
+		
+		bw.close();
+		
+		JOptionPane.showMessageDialog(this, "Done!");
+	}
+	
+	private class GeneHolder{
+		private int start;
+		private int end;
+		private double essentialityIndex;
+		private String locus_tag;
+		private String gene_symbol;
+		private String description;
+		private int length;
+		private String pValue;
+		
+		public int getStart() {
+			return start;
+		}
+		public void setStart(int start) {
+			this.start = start;
+		}
+		public int getEnd() {
+			return end;
+		}
+		public void setEnd(int end) {
+			this.end = end;
+		}
+		public Double getEssentialityIndex() {
+			return new Double(essentialityIndex);
+		}
+		public void setEssentialityIndex(double essentialityIndex) {
+			this.essentialityIndex = essentialityIndex;
+		}
+		public String getLocus_tag() {
+			return locus_tag;
+		}
+		public void setLocus_tag(String locus_tag) {
+			this.locus_tag = locus_tag;
+		}
+		public String getGene_symbol() {
+			return gene_symbol;
+		}
+		public void setGene_symbol(String gene_symbol) {
+			this.gene_symbol = gene_symbol;
+		}
+		public String getDescription() {
+			return description;
+		}
+		public void setDescription(String description) {
+			this.description = description;
+		}
+		public int getLength() {
+			return length;
+		}
+		public void setLength(int length) {
+			this.length = length;
+		}
+		public String getpValue() {
+			return pValue;
+		}
+		public void setpValue(String pValue) {
+			this.pValue = pValue;
+		}
+	}
+	
+}
diff --git a/src/CompareUtilities/CompareMain.java b/src/CompareUtilities/CompareMain.java
new file mode 100644
index 0000000..57a7f80
--- /dev/null
+++ b/src/CompareUtilities/CompareMain.java
@@ -0,0 +1,40 @@
+package CompareUtilities;
+
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+public class CompareMain {
+
+	public static final boolean DEBUG = true;
+	
+	public static void main(String[] args) {
+
+		try {
+
+			String OSName = System.getProperty("os.name");
+
+			if(OSName.contains("Windows") || OSName.contains("windows")){
+				UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+			}else{
+				UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
+			}
+		} 
+		catch (UnsupportedLookAndFeelException e) {
+
+		}
+		catch (ClassNotFoundException e) {
+			// handle exception
+		}
+		catch (InstantiationException e) {
+			// handle exception
+		}
+		catch (IllegalAccessException e) {
+			// handle exception
+		}
+
+		Compare compareFrame = new Compare();
+		compareFrame.setVisible(true);
+
+	}
+
+}
diff --git a/src/CompareUtilities/InspouDistance.java b/src/CompareUtilities/InspouDistance.java
new file mode 100644
index 0000000..3c8a067
--- /dev/null
+++ b/src/CompareUtilities/InspouDistance.java
@@ -0,0 +1,666 @@
+package CompareUtilities;
+
+import java.awt.Color;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Vector;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.ChartUtilities;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.CategoryPlot;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.data.category.DefaultCategoryDataset;
+
+public class InspouDistance {
+
+	public static void main(String[] args) {
+		InspouDistance obj = new InspouDistance();
+		obj.run();
+	}
+
+	@SuppressWarnings("unused")
+	public void run() {
+
+		for (int i = 1; i < 2; i++){
+			String libName = String.format("lib%d-0", i);
+
+			String extension = ".inspou";
+			File input = new File("/home/sina/Desktop/INSPOU/" + libName + extension);
+			//File gbkFile = new File("C:\\Users\\sina\\Desktop\\Essential Genes\\data\\inspou\\" + "NC_003911.gbk");
+			File gbkFile = new File("/home/sina/Desktop/INSPOU/" + "NC_002516.gbk");
+			Integer[] lengths = {30, 100, 300};
+
+			String extAll = " - all.xls"; 
+			File outputAll = new File("/home/sina/Desktop/INSPOU/results/" + libName + extAll);
+
+			String extSame = " - same.xls"; 
+			File outputSame = new File("/home/sina/Desktop/INSPOU/results/" + libName + extSame);
+
+			String extDiff = " - diff.xls"; 
+			File outputDiff = new File("/home/sina/Desktop/INSPOU/results/" + libName + extDiff);
+			
+			String extDiffPlusMinus = " - diff (+ , -).xls"; 
+			File outputDiffPlusMinus = new File("/home/sina/Desktop/INSPOU/results/" + libName + extDiffPlusMinus);
+			
+			String extDiffMinusPlus = " - diff (- , +).xls"; 
+			File outputDiffMinusPlus = new File("/home/sina/Desktop/INSPOU/results/" + libName + extDiffMinusPlus);
+
+			processAll(input, outputAll, libName);
+			processSame(input, outputSame, libName);
+			processDiff(input, outputDiff, libName);
+			processDiffPlusMinus(input, outputDiffPlusMinus, libName);
+			processDiffMinusPlus(input, outputDiffMinusPlus, libName);
+			
+			/*for (Integer length : lengths){
+				String fileName = libName + " - Extracted Seq with " + length + " Flank" + ".xls";
+				File outputSeq = new File("C:\\Users\\sina\\Desktop\\Essential Genes\\data\\inspou\\results\\" + fileName);
+
+				try {
+					outputSeq.delete();
+					outputSeq.createNewFile();
+					
+					extractSequence(gbkFile, input, length, outputSeq);
+				} catch (IOException e) {
+					System.out.println("IOException");
+					outputSeq.delete();
+				}
+			}*/
+			
+			input = new File("/home/sina/Desktop/INSPOU/" + libName + extension);
+			String windowInsertions = " - windows with %d insertions.xls";
+			String tempOutput = "/home/sina/Desktop/INSPOU/results/" + libName + windowInsertions;
+			processWindow(input, tempOutput);
+		}
+	}
+
+	private void processWindow(File input, String outputPath) {
+		File output = null;
+		try{
+			BufferedReader br = new BufferedReader(new FileReader(input));
+
+			String line = "";
+			Vector<Integer> numberOfInsertions = new Vector<Integer>();
+			Vector<Integer> positions = new Vector<Integer>();
+
+			line = br.readLine();
+			while(line != null){
+				String tempLine = new String(line);
+				int tempPos = Integer.parseInt(tempLine.substring(0, tempLine.indexOf("\t")));
+				tempLine = tempLine.substring(tempLine.indexOf("\t") + 1);
+				int tempNumOfIns = Integer.parseInt(tempLine.substring(tempLine.indexOf("\t") + 1));
+
+				positions.add(tempPos);
+				numberOfInsertions.add(tempNumOfIns);
+
+				line = br.readLine();
+			}
+			br.close();
+
+			Vector<Integer> insertions = new Vector<Integer>();
+			Vector<Integer> windowsCoordinates = new Vector<Integer>();
+			int currentPosition = 0;
+
+			int windowLen = 200;
+			int windowStep = 200;
+			while(currentPosition < positions.get(positions.size() - 1)){
+				int tempCount = 0;
+
+				for (int i = 0; i < numberOfInsertions.size(); i++){
+					int tempPos = positions.get(i);
+					if(tempPos >= currentPosition && tempPos < currentPosition + windowLen){
+						tempCount++;
+					}
+
+					if(tempPos > currentPosition + windowLen){
+						break;
+					}
+				}
+
+				insertions.add(tempCount);
+				windowsCoordinates.add(currentPosition);
+				currentPosition += windowStep; 
+			}
+
+			for (int j = 0; j < 5; j++){
+				output = new File(String.format(outputPath, j));
+				output.delete();
+				output.createNewFile();
+				BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+				bw.write("Start..End\tNumber of Reads\n");
+				for (int i = 0; i < windowsCoordinates.size(); i++){
+					if (insertions.get(i) == j){
+						bw.write(windowsCoordinates.get(i) + ".." + (windowsCoordinates.get(i) + 200) + "\t" + insertions.get(i) + "\n");
+					}
+				}
+
+				bw.close();
+
+			}
+
+		}catch(IOException e){
+			//System.out.println("IOException");
+			if (output != null)
+				output.delete();
+		}
+	}
+
+	private void processDiff(File input, File output, String libname) {
+		try{
+			output.delete();
+			output.createNewFile();
+
+			BufferedReader br = new BufferedReader(new FileReader(input));
+			BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+
+			String line1 = br.readLine();
+			String line2 = br.readLine();
+
+			while(line2 != null && findSign(line1).equals(findSign(line2))){
+				line1 = line2;
+				line2 = br.readLine();
+			}
+
+			int[] counts = new int[1000000];
+			int maxDiff = Integer.MIN_VALUE;
+			while(line2 != null){
+				String num1String = line1.substring(0, line1.indexOf("\t"));
+				String num2String = line2.substring(0, line2.indexOf("\t"));
+
+				int num1 = Integer.parseInt(num1String);
+				int num2 = Integer.parseInt(num2String);
+
+				int diff = num2 - num1;
+
+				counts[diff]++;
+
+				if (diff > maxDiff){
+					maxDiff = diff;
+				}
+
+				line1 = line2;
+				line2 = br.readLine();
+
+				while(line2 != null && findSign(line1).equals(findSign(line2))){
+					line1 = line2;
+					line2 = br.readLine();
+				}
+			}
+
+			bw.write("Diff.\tCount\n");
+			for (int i = 0; i <= maxDiff; i++){
+				bw.write(i + "\t" + counts[i] + "\n");
+			}
+
+			br.close();
+			bw.close();
+
+			saveChart(output, libname);
+		}catch(IOException e){
+			System.out.println("IOException");
+			output.delete();
+		}
+	}
+	
+	private void processDiffPlusMinus(File input, File output, String libname) {
+		try{
+			output.delete();
+			output.createNewFile();
+
+			BufferedReader br = new BufferedReader(new FileReader(input));
+			BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+
+			String line1 = br.readLine();
+			String line2 = br.readLine();
+
+			while(line2 != null && (findSign(line1).equals(findSign(line2)) || !findSign(line1).equals("+"))){
+				line1 = line2;
+				line2 = br.readLine();
+			}
+
+			int[] counts = new int[1000000];
+			int maxDiff = Integer.MIN_VALUE;
+			while(line2 != null){
+				String num1String = line1.substring(0, line1.indexOf("\t"));
+				String num2String = line2.substring(0, line2.indexOf("\t"));
+
+				int num1 = Integer.parseInt(num1String);
+				int num2 = Integer.parseInt(num2String);
+
+				int diff = num2 - num1;
+
+				counts[diff]++;
+
+				if (diff > maxDiff){
+					maxDiff = diff;
+				}
+
+				line1 = line2;
+				line2 = br.readLine();
+
+				while(line2 != null && (findSign(line1).equals(findSign(line2)) || !findSign(line1).equals("+"))){
+					line1 = line2;
+					line2 = br.readLine();
+				}
+			}
+
+			bw.write("Diff.\tCount\n");
+			for (int i = 0; i <= maxDiff; i++){
+				bw.write(i + "\t" + counts[i] + "\n");
+			}
+
+			br.close();
+			bw.close();
+
+			saveChart(output, libname);
+		}catch(IOException e){
+			System.out.println("IOException");
+			output.delete();
+		}
+	}
+	
+	private void processDiffMinusPlus(File input, File output, String libname) {
+		try{
+			output.delete();
+			output.createNewFile();
+
+			BufferedReader br = new BufferedReader(new FileReader(input));
+			BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+
+			String line1 = br.readLine();
+			String line2 = br.readLine();
+
+			while(line2 != null && (findSign(line1).equals(findSign(line2)) || !findSign(line1).equals("-"))){
+				line1 = line2;
+				line2 = br.readLine();
+			}
+
+			int[] counts = new int[1000000];
+			int maxDiff = Integer.MIN_VALUE;
+			while(line2 != null){
+				String num1String = line1.substring(0, line1.indexOf("\t"));
+				String num2String = line2.substring(0, line2.indexOf("\t"));
+
+				int num1 = Integer.parseInt(num1String);
+				int num2 = Integer.parseInt(num2String);
+
+				int diff = num2 - num1;
+
+				counts[diff]++;
+
+				if (diff > maxDiff){
+					maxDiff = diff;
+				}
+
+				line1 = line2;
+				line2 = br.readLine();
+
+				while(line2 != null && (findSign(line1).equals(findSign(line2)) || !findSign(line1).equals("-"))){
+					line1 = line2;
+					line2 = br.readLine();
+				}
+			}
+
+			bw.write("Diff.\tCount\n");
+			for (int i = 0; i <= maxDiff; i++){
+				bw.write(i + "\t" + counts[i] + "\n");
+			}
+
+			br.close();
+			bw.close();
+
+			saveChart(output, libname);
+		}catch(IOException e){
+			System.out.println("IOException");
+			output.delete();
+		}
+	}
+
+	private void processSame(File input, File output, String libname) {
+		try{
+			output.delete();
+			output.createNewFile();
+
+			BufferedReader br = new BufferedReader(new FileReader(input));
+			BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+
+			// Process Plus Signs
+			String line1 = br.readLine();
+			while (line1 != null && findSign(line1).equals("-")){
+				line1 = br.readLine();
+			}
+			String line2 = br.readLine();
+			while (line2 != null && findSign(line2).equals("-")){
+				line2 = br.readLine();
+			}
+
+			int[] countsPlus = new int[1000000];
+			int maxDiffPlus = Integer.MIN_VALUE;
+			while(line2 != null){
+				String num1String = line1.substring(0, line1.indexOf("\t"));
+				String num2String = line2.substring(0, line2.indexOf("\t"));
+
+				int num1 = Integer.parseInt(num1String);
+				int num2 = Integer.parseInt(num2String);
+
+				int diff = num2 - num1;
+
+				countsPlus[diff]++;
+
+				if (diff > maxDiffPlus){
+					maxDiffPlus = diff;
+				}
+
+				line1 = line2;
+				line2 = br.readLine();
+				while (line2 != null && findSign(line2).equals("-")){
+					line2 = br.readLine();
+				}
+			}
+
+			br.close();
+			bw.close();
+
+			br = new BufferedReader(new FileReader(input));
+			bw = new BufferedWriter(new FileWriter(output));
+
+			// Process Plus Signs
+			line1 = br.readLine();
+			while (line1 != null && findSign(line1).equals("+")){
+				line1 = br.readLine();
+			}
+			line2 = br.readLine();
+			while (line2 != null && findSign(line2).equals("+")){
+				line2 = br.readLine();
+			}
+
+			int[] countsMinus = new int[1000000];
+			int maxDiffMinus = Integer.MIN_VALUE;
+			while(line2 != null){
+				String num1String = line1.substring(0, line1.indexOf("\t"));
+				String num2String = line2.substring(0, line2.indexOf("\t"));
+
+				int num1 = Integer.parseInt(num1String);
+				int num2 = Integer.parseInt(num2String);
+
+				int diff = num2 - num1;
+
+				countsMinus[diff]++;
+
+				if (diff > maxDiffMinus){
+					maxDiffMinus = diff;
+				}
+
+				line1 = line2;
+				line2 = br.readLine();
+				while (line2 != null && findSign(line2).equals("+")){
+					line2 = br.readLine();
+				}
+			}
+
+			int maxDiff = maxDiffPlus > maxDiffMinus ? maxDiffPlus : maxDiffMinus;
+
+			bw.write("Diff.\tCount\n");
+			for (int i = 0; i <= maxDiff; i++){
+				bw.write(i + "\t" + (countsPlus[i] + countsMinus[i]) + "\n");
+			}
+
+			br.close();
+			bw.close();
+
+			saveChart(output, libname);
+		}catch(IOException e){
+			System.out.println("IOException");
+			output.delete();
+		}
+	}
+
+	private void processAll(File input, File output, String libname) {
+		try{
+			output.delete();
+			output.createNewFile();
+
+			BufferedReader br = new BufferedReader(new FileReader(input));
+			BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+
+			String line1 = br.readLine();
+			String line2 = br.readLine();
+
+			int[] counts = new int[1000000];
+			int maxDiff = Integer.MIN_VALUE;
+			while(line2 != null){
+				String num1String = line1.substring(0, line1.indexOf("\t"));
+				String num2String = line2.substring(0, line2.indexOf("\t"));
+
+				int num1 = Integer.parseInt(num1String);
+				int num2 = Integer.parseInt(num2String);
+
+				int diff = num2 - num1;
+
+				counts[diff]++;
+
+				if (diff > maxDiff){
+					maxDiff = diff;
+				}
+
+				line1 = line2;
+				line2 = br.readLine();
+			}
+
+			bw.write("Diff.\tCount\n");
+			for (int i = 0; i <= maxDiff; i++){
+				bw.write(i + "\t" + counts[i] + "\n");
+			}
+
+			br.close();
+			bw.close();
+
+			saveChart(output, libname);
+		}catch(IOException e){
+			System.out.println("IOException");
+			e.printStackTrace();
+			output.delete();
+		}
+	}
+
+	private int distance(String line1, String line2){
+		int pos1 = Integer.parseInt(line1.substring(0, line1.indexOf("\t")));
+		int pos2 = Integer.parseInt(line2.substring(0, line2.indexOf("\t")));
+		return Math.abs(pos1 - pos2);
+	}
+	
+	private String findSign(String line){
+		String sign = line.substring(line.indexOf("\t") + 1);
+		sign = sign.substring(0, sign.indexOf("\t"));
+		return sign;
+	}
+
+	private int findPosition(String line){
+		return Integer.parseInt(line.substring(0, line.indexOf("\t")));
+	}
+	
+	private void saveChart(File input, String libname) {
+		String outPath = input.getAbsolutePath().substring(0, input.getAbsolutePath().indexOf(".xls")) + ".png";
+		File output = null;
+		try {
+			output = new File(outPath);
+			output.delete();
+			output.createNewFile();
+
+			BufferedReader br = new BufferedReader(new FileReader(input));
+			String line = br.readLine();
+			line = br.readLine();
+
+			ArrayList<Double> xAxis = new ArrayList<Double>();
+			ArrayList<Double> yAxis = new ArrayList<Double>();
+
+			int i = 0;
+			int max = 500;
+			while(line != null){
+				xAxis.add(Double.parseDouble(line.substring(0, line.indexOf("\t"))));
+				line = line.substring(line.indexOf("\t") + 1);
+				yAxis.add(Double.parseDouble(line));
+				line = br.readLine();
+				i++;
+
+				if (i > max){
+					break;
+				}
+			}
+			br.close();
+
+			/*HistogramDataset dataset = new HistogramDataset();
+			dataset.setType(HistogramType.FREQUENCY);
+			dataset.addSeries("", Doubles.toArray(yAxis), xAxis.size());*/
+
+			DefaultCategoryDataset dataset = new DefaultCategoryDataset();
+			for (i = 0; i < yAxis.size(); i++){
+				dataset.addValue(yAxis.get(i), "Column", i + "");
+			}
+
+			String plotTitle = "Histogram for library " + libname; 
+			String xaxis = "Distance";
+			String yaxis = "Count"; 
+
+			final JFreeChart chart = ChartFactory.createBarChart(
+					plotTitle, 
+					xaxis, 
+					yaxis, 
+					dataset,                 
+					PlotOrientation.VERTICAL,
+					false,
+					false,
+					false 
+					);
+
+			chart.setBackgroundPaint(Color.white);
+
+			// get a reference to the plot for further customisation...
+			final CategoryPlot plot = chart.getCategoryPlot();
+			plot.setBackgroundPaint(Color.lightGray);
+			plot.setDomainGridlinesVisible(false);
+			plot.setRangeGridlinesVisible(false);
+			
+
+			int width = max * 20;
+			int height = max * 10; 
+
+			ChartUtilities.saveChartAsPNG(output, chart, width, height);
+		} catch (IOException e) {
+			if (output != null){
+				output.delete();
+			}
+		}
+	}
+	
+	@SuppressWarnings("unused")
+	private void extractSequence(File gbk, File input, int length, File output) throws IOException {
+		BufferedReader br = new BufferedReader(new FileReader(gbk));
+		String seqLine = br.readLine();
+		
+		ArrayList<Character> sequence = new ArrayList<Character>();
+		
+		while (!seqLine.startsWith("ORIGIN")){
+			seqLine = br.readLine();
+		}
+
+		seqLine = br.readLine();
+		while(seqLine != null){
+			seqLine = seqLine.replaceAll("\\s+","");
+			seqLine = seqLine.replaceAll("\\d","");
+			seqLine = seqLine.replaceAll("[^acgt]", "");
+			if (seqLine.length() != 0)
+				for (int k = 0; k < seqLine.length(); k++){
+					sequence.add(seqLine.charAt(k));
+				}
+			seqLine = br.readLine();
+		}
+		br.close();
+		
+		int seqLen = sequence.size();
+		
+		BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+		br = new BufferedReader(new FileReader(input));
+		
+		String line1 = br.readLine();
+		String line2 = br.readLine();
+		while(line2 != null && (findSign(line1).equals(findSign(line2)) || distance(line1, line2) != 9 || !findSign(line1).equals("+"))){
+			line1 = line2;
+			line2 = br.readLine();
+		}
+		
+		while(line2 != null){
+			int diff = distance(line1, line2);
+
+			if (diff == 9){
+				int startPos = findPosition(line1) - length - 1;
+				int endPos = findPosition(line2) + length - 1;
+				
+				StringBuilder subSeq = new StringBuilder();
+				subSeq.append(String.format(">%d..%d\r\n", (startPos + 1), (endPos + 1)));
+				//subSeq.append(">\n");
+				bw.write(subSeq.toString());
+				
+				subSeq = new StringBuilder();
+				subSeq.ensureCapacity(2 * length + 100);
+				
+				if (startPos < 0){
+					startPos = seqLen + startPos;
+					int readLength = seqLen - startPos;
+					
+					for (int i = 0; i < readLength; i++){
+						int tIndex = i + startPos;
+						subSeq.append(sequence.get(tIndex));
+					}
+					
+					readLength = endPos;
+					for (int i = 0; i <= readLength; i++){
+						int tIndex = i + 0;
+						subSeq.append(sequence.get(tIndex));
+					}
+				}else if (endPos >= seqLen){
+					endPos = endPos - seqLen;
+					int readLength = seqLen - startPos;
+					
+					for (int i = 0; i < readLength; i++){
+						int tIndex = i + startPos;
+						subSeq.append(sequence.get(tIndex));
+					}
+					
+					readLength = endPos;
+					for (int i = 0; i <= readLength; i++){
+						int tIndex = i + 0;
+						subSeq.append(sequence.get(tIndex));
+					}
+				}else{
+					System.out.print("");
+					
+					for (int i = 0; i <= endPos - startPos; i++){
+						int tIndex = i + startPos;
+						subSeq.append(sequence.get(tIndex));
+					}
+				}
+				
+				bw.write(subSeq.toString() + "\r\n");
+				
+			} // End of IF
+			
+			line1 = line2;
+			line2 = br.readLine();
+
+			while(line2 != null && (findSign(line1).equals(findSign(line2)) || distance(line1, line2) != 9 || !findSign(line1).equals("+"))){
+				line1 = line2;
+				line2 = br.readLine();
+			}
+		}
+
+		bw.close();
+		br.close();
+	}
+
+}
diff --git a/src/CompareUtilities/Utilities.java b/src/CompareUtilities/Utilities.java
new file mode 100644
index 0000000..dc7d587
--- /dev/null
+++ b/src/CompareUtilities/Utilities.java
@@ -0,0 +1,64 @@
+package CompareUtilities;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JTextField;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import CustomGUIComponent.FolderChooser;
+
+public class Utilities {
+
+	public static String browseForFolder(JFrame parent){
+		Path currentRelativePath = Paths.get("");
+		String location = currentRelativePath.toAbsolutePath().toString();
+
+		String OSName = System.getProperty("os.name");
+
+		JFileChooser fileChooser = null;
+		int result = -1;
+		if(OSName.contains("Windows") || OSName.contains("windows")){
+			fileChooser = new FolderChooser();
+			fileChooser.setCurrentDirectory(new File(location));
+			fileChooser.setDialogTitle("Select a folder to store the new project in it");
+			result = fileChooser.showSaveDialog(parent);					
+		}else{
+			JOptionPane.showMessageDialog(parent, "Select a folder to store the new project in it");
+			fileChooser = new JFileChooser();
+			fileChooser.setCurrentDirectory(new File(location));
+			fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+			fileChooser.setDialogTitle("Select a folder to store the new project in it");
+			result = fileChooser.showSaveDialog(parent);
+		}
+
+		if (result == JFileChooser.APPROVE_OPTION){
+			return fileChooser.getSelectedFile().getAbsolutePath() + File.separator;
+		}
+
+		return null;
+	}
+	
+	public static void browseForInputFile(JTextField text, String ext, String extInfo, JFrame parent){
+
+		Path currentRelativePath = Paths.get("");
+		String location = currentRelativePath.toAbsolutePath()
+				.toString();
+		JFileChooser fileChooser = new JFileChooser(location);
+		fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+		fileChooser.setFileFilter(new FileNameExtensionFilter(extInfo, ext));
+		int result = fileChooser.showOpenDialog(parent);
+
+		if(result == JFileChooser.APPROVE_OPTION){
+			text.setText(fileChooser.getSelectedFile().getAbsolutePath());
+		}else{
+			return;
+		}
+
+	}
+	
+}
diff --git a/src/CustomGUIComponent/BoldCellRenderer.java b/src/CustomGUIComponent/BoldCellRenderer.java
new file mode 100644
index 0000000..0e179d2
--- /dev/null
+++ b/src/CustomGUIComponent/BoldCellRenderer.java
@@ -0,0 +1,19 @@
+package CustomGUIComponent;
+
+import java.awt.Component;
+import java.awt.Font;
+
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableCellRenderer;
+
+ at SuppressWarnings("serial")
+public class BoldCellRenderer extends DefaultTableCellRenderer {
+	@Override
+	public Component getTableCellRendererComponent(JTable table, Object aValue,
+			boolean isSelected, boolean hasFocus, int rowIndex, int columnIndex) {
+		Component component = super.getTableCellRendererComponent(table, aValue, isSelected, hasFocus, rowIndex, columnIndex);
+		//component.setFont(component.getFont().deriveFont(Font.BOLD));
+		component.setFont(new Font("Arial" , Font.BOLD, 11));
+		return component;
+	}
+}
diff --git a/src/CustomGUIComponent/FolderChooser.java b/src/CustomGUIComponent/FolderChooser.java
new file mode 100644
index 0000000..04c5222
--- /dev/null
+++ b/src/CustomGUIComponent/FolderChooser.java
@@ -0,0 +1,57 @@
+package CustomGUIComponent;
+
+import java.awt.Component;
+import java.awt.FlowLayout;
+
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JPanel;
+import javax.swing.JToolBar;
+
+import sun.swing.FilePane;
+
+public class FolderChooser extends JFileChooser {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	@SuppressWarnings("unused")
+	public FolderChooser(){
+		setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+		
+		remove(getComponent(0));
+		JPanel folderView = (JPanel)getComponent(1);
+		JToolBar toolbar = (JToolBar)getComponent(0);
+		
+		toolbar.remove(toolbar.getComponent(0));
+		toolbar.remove(toolbar.getComponent(0));
+		Component tree = toolbar.getComponent(0);
+		toolbar.remove(toolbar.getComponent(1));
+		toolbar.remove(toolbar.getComponent(2));
+		toolbar.remove(toolbar.getComponent(2));
+		toolbar.remove(toolbar.getComponent(2));
+		
+		folderView.remove(folderView.getComponent(0));
+		
+		FilePane folders = (FilePane)folderView.getComponent(0);
+		folders.setViewType(FilePane.VIEWTYPE_DETAILS);
+		
+		JPanel buttonsPanel = (JPanel)folderView.getComponent(1);
+		buttonsPanel.remove(buttonsPanel.getComponent(0));
+		buttonsPanel.remove(buttonsPanel.getComponent(0));
+		buttonsPanel.remove(buttonsPanel.getComponent(0));
+		buttonsPanel.remove(buttonsPanel.getComponent(0));
+		
+		JPanel buttons = (JPanel)buttonsPanel.getComponent(0);
+		buttons.setLayout(new FlowLayout());
+		buttons.revalidate();
+		
+		JButton saveBtn = (JButton)buttons.getComponent(1);
+		JButton cancelBtn = (JButton)buttons.getComponent(3);
+		
+		revalidate();
+	}
+
+}
diff --git a/src/CustomGUIComponent/IntegerInputVerifier.java b/src/CustomGUIComponent/IntegerInputVerifier.java
new file mode 100644
index 0000000..0e9b671
--- /dev/null
+++ b/src/CustomGUIComponent/IntegerInputVerifier.java
@@ -0,0 +1,43 @@
+package CustomGUIComponent;
+
+import java.awt.Color;
+
+import javax.swing.InputVerifier;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+
+public class IntegerInputVerifier extends InputVerifier{
+
+	JLabel errorLabel = null;
+
+	public IntegerInputVerifier(JLabel errorMsgLbl) {
+		errorLabel = errorMsgLbl;
+	}
+
+	@Override
+	public boolean verify(JComponent input) {
+		JTextField textField = (JTextField) input;
+		boolean isInteger = true;
+
+		try{
+			int a = Integer.parseInt(textField.getText());
+			if (a < 0){
+				isInteger = false;
+			}
+		}catch(NumberFormatException e){
+			isInteger = false;
+		}
+
+		if (isInteger){
+			textField.setBackground(new Color(228, 252, 230)/*GREEN*/);
+			errorLabel.setVisible(false);
+		}else{
+			textField.setBackground(new Color(255, 177, 194)/*RED*/);
+			errorLabel.setVisible(true);
+		}
+
+		return true;
+	}
+
+}
diff --git a/src/CustomGUIComponent/MyChartMouseListener.java b/src/CustomGUIComponent/MyChartMouseListener.java
new file mode 100644
index 0000000..eddbda3
--- /dev/null
+++ b/src/CustomGUIComponent/MyChartMouseListener.java
@@ -0,0 +1,37 @@
+package CustomGUIComponent;
+
+import javax.swing.JLabel;
+
+import org.jfree.chart.ChartMouseEvent;
+import org.jfree.chart.ChartMouseListener;
+import org.jfree.chart.entity.XYItemEntity;
+import org.jfree.data.xy.XYSeriesCollection;
+
+public class MyChartMouseListener implements ChartMouseListener {
+
+	private JLabel infoLbl;
+	
+	public MyChartMouseListener() {
+		super();
+	}
+	
+	public MyChartMouseListener(JLabel infoLbl) {
+		this();
+		this.infoLbl = infoLbl;
+	}
+	
+	@Override
+	public void chartMouseClicked(ChartMouseEvent e) {
+		
+	}
+
+	@Override
+	public void chartMouseMoved(ChartMouseEvent e) {
+		if (e.getEntity().getClass() == XYItemEntity.class){
+			XYItemEntity item = (XYItemEntity) e.getEntity();
+			XYSeriesCollection dataset = (XYSeriesCollection) item.getDataset();
+			infoLbl.setText(((MyXYDataItem)dataset.getSeries(0).getItems().get(item.getItem())).getInfo());
+		}
+	}
+
+}
diff --git a/src/CustomGUIComponent/MyXYDataItem.java b/src/CustomGUIComponent/MyXYDataItem.java
new file mode 100644
index 0000000..e1bcfc6
--- /dev/null
+++ b/src/CustomGUIComponent/MyXYDataItem.java
@@ -0,0 +1,26 @@
+package CustomGUIComponent;
+
+import org.jfree.data.xy.XYDataItem;
+
+public class MyXYDataItem extends XYDataItem {
+
+	private static final long serialVersionUID = -3641354962307531846L;
+	private String info;
+	
+	public MyXYDataItem(double x, double y) {
+		super(x, y);
+	}
+
+	public MyXYDataItem(double x, double y, String info) {
+		super(x, y);
+		this.setInfo(info);
+	}
+	
+	public String getInfo() {
+		return info;
+	}
+
+	public void setInfo(String info) {
+		this.info = info;
+	}
+}
diff --git a/src/CustomGUIComponent/PercentageInputVerifier.java b/src/CustomGUIComponent/PercentageInputVerifier.java
new file mode 100644
index 0000000..3c73073
--- /dev/null
+++ b/src/CustomGUIComponent/PercentageInputVerifier.java
@@ -0,0 +1,53 @@
+package CustomGUIComponent;
+
+import java.awt.Color;
+import java.awt.Component;
+
+import javax.swing.InputVerifier;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+
+public class PercentageInputVerifier extends InputVerifier{
+
+	JLabel errorLabel = null;
+	Component actionComponent = null;
+	
+	public PercentageInputVerifier(JLabel errorMsgLbl, Component actionComponent) {
+		errorLabel = errorMsgLbl;
+		this.actionComponent = actionComponent;
+	}
+
+	@Override
+	public boolean verify(JComponent input) {
+	
+		JTextField textField = (JTextField) input;
+		boolean valid = true;
+		
+		String text = textField.getText();
+		text = text.replace("%", "");
+		
+		try{
+			Double.parseDouble(text);
+		}catch(NumberFormatException e){
+			valid = false;
+		}
+		
+		if (valid){
+			textField.setBackground(new Color(228, 252, 230)/*GREEN*/);
+			errorLabel.setVisible(false);
+			if (actionComponent != null){
+				actionComponent.setEnabled(true);
+			}
+		}else{
+			textField.setBackground(new Color(255, 177, 194)/*RED*/);
+			errorLabel.setVisible(true);
+			if (actionComponent != null){
+				actionComponent.setEnabled(false);
+			}
+		}
+			
+		return true;
+	}
+
+}
diff --git a/src/GUI/AboutFrame.java b/src/GUI/AboutFrame.java
new file mode 100644
index 0000000..f7719e2
--- /dev/null
+++ b/src/GUI/AboutFrame.java
@@ -0,0 +1,38 @@
+package GUI;
+
+import java.awt.Font;
+
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+
+ at SuppressWarnings("serial")
+public class AboutFrame extends JFrame {
+
+	private JPanel contentPane;
+	
+	/**
+	 * Create the frame.
+	 */
+	public AboutFrame() {
+		setTitle("About");
+		setResizable(false);
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		setBounds(100, 100, 450, 300);
+		contentPane = new JPanel();
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		setContentPane(contentPane);
+		contentPane.setLayout(null);
+		
+		JLabel lblTnseqExplorer = new JLabel("");
+		lblTnseqExplorer.setIcon(new ImageIcon(AboutFrame.class.getResource("/resources/info.png")));
+		lblTnseqExplorer.setFont(new Font("Tahoma", Font.PLAIN, 18));
+		lblTnseqExplorer.setBounds(0, 22, 424, 250);
+		contentPane.add(lblTnseqExplorer);
+		
+		setLocationRelativeTo(null);
+		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+	}
+}
diff --git a/src/GUI/AddMoreIndices.java b/src/GUI/AddMoreIndices.java
new file mode 100644
index 0000000..7660a84
--- /dev/null
+++ b/src/GUI/AddMoreIndices.java
@@ -0,0 +1,1355 @@
+package GUI;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.JSeparator;
+import javax.swing.JTabbedPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.table.DefaultTableModel;
+
+import org.apache.log4j.Logger;
+import org.jdesktop.swingx.JXLabel;
+import org.jfree.chart.ChartPanel;
+
+import CustomGUIComponent.BoldCellRenderer;
+import CustomGUIComponent.IntegerInputVerifier;
+import CustomGUIComponent.MyChartMouseListener;
+import CustomGUIComponent.PercentageInputVerifier;
+import essgenes.AddColumns;
+import essgenes.Messages;
+import essgenes.PlotData;
+import essgenes.ProjectInfo;
+
+ at SuppressWarnings("serial")
+public class AddMoreIndices extends JFrame {
+
+	private Logger logger = Logger.getLogger(AddMoreIndices.class.getName());
+	private String tableName = "";
+	private boolean logPlot = false;
+	private ProjectInfo info = null;
+	@SuppressWarnings("unused")
+	private JFrame parentFrame = null;
+
+	private JButton densityFNABtn = new JButton("Browse");
+	private JCheckBox densityNormalizeTAChk = new JCheckBox("Normalized to TA sites instead of gene length");
+	private JRadioButton step2UniqueRadio = new JRadioButton("Count only unique insertions");
+	private JRadioButton step2AllRadio = new JRadioButton("Count all sequence reads");
+	private JButton step2PlotBtn = new JButton("Plot");
+	private JComboBox<String> step2ColumnCombo = new JComboBox<String>();
+	private JLabel step2ErrorLbl = new JLabel("Please enter a valid value in the red fields.");
+	private JLabel step2WaitLbl = new JLabel("Please wait...");
+	private JComboBox<String> step2Combo = new JComboBox<String>();	
+	private JLabel errorMsg2Lbl = new JLabel("Please enter a valid value in the red fields.");
+	private JLabel errorMsg1Lbl = new JLabel("Please enter a valid value in the red fields.");
+	private JPanel contentPane;
+	private JTextField addWinLenTxt;
+	private JTextField addStepTxt;
+	private JTextField adjustStartTxt;
+	private JTextField adjustEndTxt;
+	private JTextField addSeqLenTxt;
+	private JComboBox<String> addLibraryCombo = new JComboBox<String>();
+	private JTextField tableNameTxt;
+	private JLabel lblPleaseWait = new JLabel("Please wait...");
+	private JButton addMoreColumnsBtn = new JButton("Execute");
+	private JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
+	private JComboBox<String> countInsLibCombo = new JComboBox<String>();
+	private JTextField countInsAdjStartTxt;
+	private JTextField countInsAdjEndTxt;
+	private JButton countInsBtn = new JButton("Count");
+	private JLabel countInsPleaseWaitLbl = new JLabel("Please wait...");
+	private JTable compareTable;
+	private JScrollPane scrollPane = new JScrollPane();
+	private JTextField compareMaxInsTxt;
+	private JComboBox<String> columnOneCombo = new JComboBox<String>();
+	private JComboBox<String> columnTwoCombo = new JComboBox<String>();
+	private JButton compareBtn = new JButton("Difference");
+	private JLabel compareWaitLbl = new JLabel("Please wait...");
+	private JCheckBox logPlotCheck = new JCheckBox("Logarithmic Plot");
+	private JRadioButton newDataUniqueInsertionRadio = new JRadioButton("Count only unique insertions");
+	private JRadioButton newDataAllReadsRadio = new JRadioButton("Count all sequence reads");
+	private JRadioButton countInsUniqueInsertionRadio = new JRadioButton("Count only unique insertions");
+	private JRadioButton countInsAllReadsRadio = new JRadioButton("Count all sequence reads");
+	private JCheckBox randomizePlotDataChk = new JCheckBox("Randomize data");
+	private JProgressBar progressBar = new JProgressBar();
+	private JTextField step2AdjustStart;
+	private JTextField step2AdjustEnd;
+	private JTextField step2AverageTxt;
+	private JTextField densityFNATxt;
+	
+	/**
+	 * Create the frame.
+	 */
+	public AddMoreIndices(String tableName, ProjectInfo info, JFrame parentFrame){
+		this();
+
+		this.tableName = tableName;
+		tableNameTxt.setText(tableName);
+		this.info = info;
+		this.parentFrame = parentFrame;
+
+		setTitle("Add new essentiality indices to \"" + tableName + "\" table");
+		setLocationRelativeTo(parentFrame);
+				
+		initializeAddPanel();
+		tabbedPane.addChangeListener(new ChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent e) {
+				int selectedTab = tabbedPane.getSelectedIndex();
+
+				if (selectedTab == 0){
+					initializeAddPanel();
+				}
+
+				if (selectedTab == 1){
+					initializeDensityInsertions();
+				}
+				
+				if (selectedTab == 2){
+					initializeCountInsertions();
+				}
+
+				if(selectedTab == 3){
+					initializeCompare();
+				}			
+			}
+		});
+		
+		ButtonGroup newData_group = new ButtonGroup();
+		newData_group.add(newDataAllReadsRadio);
+		newData_group.add(newDataUniqueInsertionRadio);
+		
+		ButtonGroup countIns_group = new ButtonGroup();
+		countIns_group.add(countInsAllReadsRadio);
+		countIns_group.add(countInsUniqueInsertionRadio);
+	}
+	
+	private void initializeCompare(){
+		compareWaitLbl.setVisible(false);
+		
+		try {
+			DefaultTableModel model = AddColumns.getHeaderData(tableName, info);
+			compareTable = new JTable(model);
+		} catch (IOException e) {
+			logger.error("There was an error while creating the header table.");
+			return;
+		}
+		//compareTable.setBounds(0, 0, 536 - 10, 159 - 11);
+		compareTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+		compareTable.setCellSelectionEnabled(false);
+		compareTable.getColumnModel().getColumn(0).setCellRenderer(new BoldCellRenderer());
+		compareTable.getTableHeader().setFont(new Font("Arial" , Font.BOLD, 11));
+
+		//scrollPane.setBounds(10, 11, 536, 159);
+		scrollPane.add(compareTable);
+		scrollPane.setViewportView(compareTable);
+		
+		int firstCombo = columnOneCombo.getSelectedIndex();
+		int secondCombo = columnTwoCombo.getSelectedIndex();
+		
+		columnOneCombo.removeAllItems();
+		columnTwoCombo.removeAllItems();
+		for (int i = 0; i < compareTable.getColumnCount(); i++){
+			if(i == 0){
+				columnOneCombo.addItem("");
+				columnTwoCombo.addItem("");
+			}else{
+				columnOneCombo.addItem(i + "");
+				columnTwoCombo.addItem(i + "");
+			}
+		}
+	
+		columnOneCombo.setSelectedIndex(firstCombo);
+		columnTwoCombo.setSelectedIndex(secondCombo);
+		
+	}
+	
+	private void initializeDensityInsertions(){
+		BufferedReader br = null;
+		if(step2Combo != null){
+			step2Combo.removeAllItems();
+		}
+		
+		step2WaitLbl.setVisible(false);
+		step2ErrorLbl.setVisible(false);
+		
+		try{
+			br = new BufferedReader(new FileReader(info.getFile()));
+
+			String line = br.readLine();
+			br.readLine();
+			br.readLine();
+
+			while(line != null){
+				line = br.readLine();
+
+				if (line != null)
+					step2Combo.addItem(line.substring(0, line.length() - 6));
+
+				line = br.readLine();
+				line = br.readLine();
+				line = br.readLine();
+			}
+
+			br.close();
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return;
+		}
+		
+		try{
+			br = new BufferedReader(new FileReader(new File(info.getPath() + tableName + ".table.xls")));
+			
+			br.readLine();
+			br.readLine();
+			String[] titles = br.readLine().split("\t");
+			
+			int count = 0;
+			step2ColumnCombo.removeAllItems();
+			for (String title : titles){
+				if (title.contains("density")){
+					step2ColumnCombo.addItem(count + ":\t" + title);
+				}
+				count++;
+			}
+			br.close();
+		}catch (IOException e){
+			logger.error(e.getMessage());
+			return;
+		}catch (NullPointerException e1) {
+			JOptionPane.showMessageDialog(null, "");
+			try {
+				br.close();
+			} catch (IOException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+		}
+		
+	}
+	
+	private void initializeCountInsertions(){
+
+		BufferedReader br = null;
+
+		if(countInsLibCombo != null){
+			countInsLibCombo.removeAllItems();
+		}
+		
+		countInsPleaseWaitLbl.setVisible(false);
+
+		try{
+			br = new BufferedReader(new FileReader(info.getFile()));
+
+			String line = br.readLine();
+			br.readLine();
+			br.readLine();
+
+			while(line != null){
+				line = br.readLine();
+
+				if (line != null)
+					countInsLibCombo.addItem(line.substring(0, line.length() - 6));
+
+				line = br.readLine();
+				line = br.readLine();
+				line = br.readLine();
+			}
+
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return;
+		}finally{
+			try{
+				br.close();
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return;
+			}
+		}
+	
+	}
+	
+	public AddMoreIndices() {
+		setResizable(false);
+		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+		setBounds(100, 100, 767, 522);
+		contentPane = new JPanel();
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		setContentPane(contentPane);
+		contentPane.setLayout(null);
+
+		tabbedPane.setBounds(10, 11, 743, 469);
+		contentPane.add(tabbedPane);
+
+		JPanel panel = new JPanel();
+		tabbedPane.addTab("Add new essentiality indices", null, panel, null);
+		panel.setLayout(null);
+
+		JLabel lblChooseALibrary = new JLabel("Choose a library:");
+		lblChooseALibrary.setBounds(10, 63, 137, 14);
+		panel.add(lblChooseALibrary);
+		addLibraryCombo.addItemListener(new ItemListener() {
+			public void itemStateChanged(ItemEvent arg0) {
+				BufferedReader br = null;
+				try{
+					File winInfo = new File(info.getPath() + addLibraryCombo.getSelectedItem() + ".data");
+					if (winInfo.exists()){
+						br = new BufferedReader(new FileReader(winInfo));
+						String line = br.readLine();
+						int tempLen = Integer.parseInt(line.substring(line.indexOf("=") + 2, line.length()));
+						line = br.readLine();
+						int tempStep = Integer.parseInt(line.substring(line.indexOf("=") + 2, line.length()));
+						br.close();
+						
+						addWinLenTxt.setText(tempLen + "");
+						addStepTxt.setText(tempStep + "");
+						
+					}
+				}catch (IOException e){
+					logger.fatal(e.getMessage());
+				}	
+			}
+		});
+		addLibraryCombo.setToolTipText("Choose a library to use for adding datat to the table");
+
+		addLibraryCombo.setBounds(157, 60, 569, 20);
+		panel.add(addLibraryCombo);
+
+		addWinLenTxt = new JTextField();
+		addWinLenTxt.setToolTipText("Window length to used for adding data");
+		addWinLenTxt.setText("1000");
+		addWinLenTxt.setColumns(10);
+		addWinLenTxt.setBounds(157, 122, 86, 20);
+		addWinLenTxt.setInputVerifier(new IntegerInputVerifier(errorMsg1Lbl));
+		panel.add(addWinLenTxt);
+
+		addStepTxt = new JTextField();
+		addStepTxt.setToolTipText("Window steps to used for adding data");
+		addStepTxt.setText("10");
+		addStepTxt.setColumns(10);
+		addStepTxt.setBounds(512, 124, 86, 20);
+		addStepTxt.setInputVerifier(new IntegerInputVerifier(errorMsg1Lbl));
+		panel.add(addStepTxt);
+
+		JLabel lblWindowLength = new JLabel("Window length:");
+		lblWindowLength.setBounds(10, 125, 137, 14);
+		panel.add(lblWindowLength);
+
+		JLabel label_3 = new JLabel("Step:");
+		label_3.setBounds(387, 127, 137, 14);
+		panel.add(label_3);
+
+		adjustStartTxt = new JTextField();
+		adjustStartTxt.setToolTipText("You can also omit percent sign and use regular number");
+		adjustStartTxt.setText("-5%");
+		adjustStartTxt.setColumns(10);
+		adjustStartTxt.setInputVerifier(new PercentageInputVerifier(errorMsg1Lbl, addMoreColumnsBtn));
+		adjustStartTxt.setBounds(157, 153, 86, 20);
+		panel.add(adjustStartTxt);
+
+		JLabel lblAdjustGeneStart = new JLabel("Adjust gene start:");
+		lblAdjustGeneStart.setBounds(10, 156, 137, 14);
+		panel.add(lblAdjustGeneStart);
+
+		adjustEndTxt = new JTextField();
+		adjustEndTxt.setToolTipText("You can also omit percent sign and use regular number");
+		adjustEndTxt.setText("-20%");
+		adjustEndTxt.setColumns(10);
+		adjustEndTxt.setBounds(512, 155, 86, 20);
+		adjustEndTxt.setInputVerifier(new PercentageInputVerifier(errorMsg1Lbl, addMoreColumnsBtn));
+		panel.add(adjustEndTxt);
+
+		JLabel lblAdjustGeneEnd = new JLabel("Adjust gene end:");
+		lblAdjustGeneEnd.setBounds(387, 158, 137, 14);
+		panel.add(lblAdjustGeneEnd);
+
+		addSeqLenTxt = new JTextField();
+		addSeqLenTxt.setToolTipText("Loaded from the main project");
+		addSeqLenTxt.setEditable(false);
+		addSeqLenTxt.setColumns(10);
+		addSeqLenTxt.setBounds(157, 184, 86, 20);
+		panel.add(addSeqLenTxt);
+
+		JLabel lblSequenceLength = new JLabel("Sequence length:");
+		lblSequenceLength.setBounds(10, 187, 137, 14);
+		panel.add(lblSequenceLength);
+
+		addMoreColumnsBtn.setToolTipText("Start adding data to the specific table");
+		addMoreColumnsBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				addBtnAction();
+			}
+		});
+		addMoreColumnsBtn.setBounds(606, 412, 120, 23);
+		panel.add(addMoreColumnsBtn);
+		
+		tableNameTxt = new JTextField();
+		tableNameTxt.setToolTipText("Selected data table in the main project");
+		tableNameTxt.setEditable(false);
+		tableNameTxt.setBounds(157, 91, 569, 20);
+		panel.add(tableNameTxt);
+		tableNameTxt.setColumns(10);
+		
+		JLabel lblSelectedTable = new JLabel("Selected table:");
+		lblSelectedTable.setBounds(10, 94, 137, 14);
+		panel.add(lblSelectedTable);
+		
+		lblPleaseWait.setIcon(new ImageIcon(AddMoreIndices.class.getResource("/resources/load.gif")));
+		lblPleaseWait.setBounds(205, 416, 185, 14);
+		lblPleaseWait.setVisible(false);
+		panel.add(lblPleaseWait);
+		
+		JLabel label = new JLabel("(?)");
+		label.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, ""
+						+ "Specifies the window size in base pairs. Larger window sizes differentiate more accurately between\n"
+						+ "essential and non-essential genes for genes larger than the window size but they can miss essential\n"
+						+ "genes smaller than the window size.");
+			}
+		});
+		label.setToolTipText("Click me!");
+		label.setForeground(Color.BLUE);
+		label.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label.setBounds(253, 125, 88, 14);
+		panel.add(label);
+		
+		JLabel label_1 = new JLabel("(?)");
+		label_1.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, ""
+						+ "This parameter automatically adjusts the start coordinates for all genes. To leave the gene start\n"
+						+ "coordinates as annotated, use zero. To shorten the gene at the 5� end by a specific number of\n"
+						+ "nucleotides use a negative number (for example, -50 will eliminate first 50 base pairs of each gene). The\n"
+						+ "value 50 or +50 would add 50 upstream nucleotides to the gene. Including the % sign will make the\n"
+						+ "adjustments relative to the gene length. For example, -5% will shorten the gene by 5% of its length at\n"
+						+ "the 5� end. Generally, you may want to exclude a short segment at the start of the gene to account for\n"
+						+ "possibly misannotated gene start sites.");
+			}
+		});
+		label_1.setToolTipText("Click me!");
+		label_1.setForeground(Color.BLUE);
+		label_1.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_1.setBounds(253, 156, 88, 14);
+		panel.add(label_1);
+		
+		JLabel label_8 = new JLabel("(?)");
+		label_8.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, ""
+						+ "The step at which the window is moved along the sequence. Shorter step sizes provide better resolution\n"
+						+ "(1 is optimal) but the calculations with smaller step sizes will take longer.");	
+			}
+		});
+		label_8.setToolTipText("Click me!");
+		label_8.setForeground(Color.BLUE);
+		label_8.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_8.setBounds(608, 127, 88, 14);
+		panel.add(label_8);
+		
+		JLabel label_9 = new JLabel("(?)");
+		label_9.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, ""
+						+ "This parameter automatically adjusts the end coordinates for all genes. To leave the gene end\n"
+						+ "coordinates as annotated, use zero. To shorten the gene at the 3rd end by a specific number of\n"
+						+ "nucleotides use a negative number (for example, -50 will eliminate last 50 base pairs of each gene). The\n"
+						+ "value 50 or +50 would add 50 downstream nucleotides to the gene. Including the % sign will make the\n"
+						+ "adjustments relative to the gene length. For example, -20% will shorten the gene by 20% of its length at\n"
+						+ "the 3rd end. Generaly, you may want to exclude the 3rd end of the gene from the analysis because\n"
+						+ "transposon insertions near the end of the gene are less likely to be deletrious.");
+			}
+		});
+		label_9.setToolTipText("Click me!");
+		label_9.setForeground(Color.BLUE);
+		label_9.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_9.setBounds(608, 158, 88, 14);
+		panel.add(label_9);
+		
+		newDataUniqueInsertionRadio.setSelected(true);
+		newDataUniqueInsertionRadio.setBounds(387, 182, 281, 23);
+		panel.add(newDataUniqueInsertionRadio);
+		
+		newDataAllReadsRadio.setBounds(387, 208, 281, 23);
+		panel.add(newDataAllReadsRadio);
+		
+		JXLabel lblThisToolWill = new JXLabel("This tool will add essentiality indices for all genes in the selected table. The lower the essentiality index the more likely it is that the given gene is essential.");
+		lblThisToolWill.setBounds(10, 11, 716, 42);
+		lblThisToolWill.setLineWrap(true);
+		panel.add(lblThisToolWill);
+		
+		progressBar.setBounds(10, 416, 185, 14);
+		panel.add(progressBar);
+		
+		errorMsg1Lbl.setForeground(Color.RED);
+		errorMsg1Lbl.setBounds(10, 391, 434, 14);
+		errorMsg1Lbl.setVisible(false);
+		panel.add(errorMsg1Lbl);
+		
+		JPanel panel_1 = new JPanel();
+		tabbedPane.addTab("Add insertion density", null, panel_1, null);
+		panel_1.setLayout(null);
+		
+		JLabel label_6 = new JLabel("This tool adds a new data column with the count of insertions or read counts in each gene.");
+		label_6.setBounds(10, 11, 716, 14);
+		panel_1.add(label_6);
+		
+		JLabel label_7 = new JLabel("Choose a library:");
+		label_7.setBounds(10, 39, 137, 14);
+		panel_1.add(label_7);
+		
+		step2Combo.setToolTipText("Choose a library to use for adding datat to the table");
+		step2Combo.setBounds(157, 36, 569, 20);
+		panel_1.add(step2Combo);
+		
+		JLabel label_11 = new JLabel("Adjust gene start:");
+		label_11.setBounds(10, 67, 137, 14);
+		panel_1.add(label_11);
+		
+		step2AdjustStart = new JTextField();
+		step2AdjustStart.setToolTipText("You can also omit percent sign and use regular number");
+		step2AdjustStart.setText("-5%");
+		step2AdjustStart.setColumns(10);
+		step2AdjustStart.setBounds(157, 64, 86, 20);
+		panel_1.add(step2AdjustStart);
+		
+		JLabel label_13 = new JLabel("(?)");
+		label_13.setToolTipText("Click me!");
+		label_13.setForeground(Color.BLUE);
+		label_13.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_13.setBounds(253, 67, 88, 14);
+		panel_1.add(label_13);
+		
+		JLabel label_14 = new JLabel("Adjust gene end:");
+		label_14.setBounds(350, 67, 137, 14);
+		panel_1.add(label_14);
+		
+		step2AdjustEnd = new JTextField();
+		step2AdjustEnd.setToolTipText("You can also omit percent sign and use regular number");
+		step2AdjustEnd.setText("-20%");
+		step2AdjustEnd.setColumns(10);
+		step2AdjustEnd.setBounds(475, 64, 86, 20);
+		panel_1.add(step2AdjustEnd);
+		
+		JLabel label_15 = new JLabel("(?)");
+		label_15.setToolTipText("Click me!");
+		label_15.setForeground(Color.BLUE);
+		label_15.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_15.setBounds(571, 67, 88, 14);
+		panel_1.add(label_15);
+		
+		step2UniqueRadio.setSelected(true);
+		step2UniqueRadio.setBounds(10, 88, 281, 23);
+		panel_1.add(step2UniqueRadio);
+
+		step2AllRadio.setBounds(10, 114, 281, 23);
+		panel_1.add(step2AllRadio);
+		
+		ButtonGroup step2BtnGroup = new ButtonGroup();
+		step2BtnGroup.add(step2UniqueRadio);
+		step2BtnGroup.add(step2AllRadio);
+		
+		JButton btnAdd = new JButton("Add");
+		btnAdd.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				calcInsertionDensity();
+			}
+		});
+		btnAdd.setBounds(637, 205, 89, 23);
+		panel_1.add(btnAdd);
+		
+		step2WaitLbl.setIcon(new ImageIcon(AddMoreIndices.class.getResource("/resources/load.gif")));
+		step2WaitLbl.setBounds(10, 415, 164, 15);
+		panel_1.add(step2WaitLbl);
+		
+		step2ErrorLbl.setForeground(Color.RED);
+		step2ErrorLbl.setBounds(10, 388, 370, 15);
+		panel_1.add(step2ErrorLbl);
+		
+		JSeparator separator = new JSeparator();
+		separator.setBounds(11, 251, 716, 2);
+		panel_1.add(separator);
+		
+		JLabel lblPlotDensity = new JXLabel("Plot density / number of insertions:");
+		lblPlotDensity.setBounds(11, 265, 716, 15);
+		panel_1.add(lblPlotDensity);
+		
+		JLabel lblChooseAColumn = new JLabel("Choose a column in the table:");
+		lblChooseAColumn.setBounds(11, 292, 281, 15);
+		panel_1.add(lblChooseAColumn);
+		
+		step2ColumnCombo.setBounds(254, 287, 473, 24);
+		panel_1.add(step2ColumnCombo);
+		
+		step2PlotBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				plotDensities();
+			}
+		});
+		step2PlotBtn.setBounds(638, 352, 89, 25);
+		panel_1.add(step2PlotBtn);
+		
+		JLabel lblAverageNumberOf = new JLabel("Smoothness");
+		lblAverageNumberOf.setBounds(10, 325, 234, 14);
+		panel_1.add(lblAverageNumberOf);
+		
+		step2AverageTxt = new JTextField();
+		step2AverageTxt.setText("20");
+		step2AverageTxt.setBounds(254, 322, 86, 20);
+		panel_1.add(step2AverageTxt);
+		step2AverageTxt.setColumns(10);
+		
+		JLabel label_16 = new JLabel("(?)");
+		label_16.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, "This parameter determines the smoothness of the histogram. The higher values\n"
+						+ "result in smoother plots. The size of density bins is set such that the average\n"
+						+ "number of genes in each bin is close to the value of this parameter.");
+			}
+		});
+		label_16.setToolTipText("Click me!");
+		label_16.setForeground(Color.BLUE);
+		label_16.setFont(new Font("Dialog", Font.PLAIN, 11));
+		label_16.setBounds(351, 325, 88, 14);
+		panel_1.add(label_16);
+		densityNormalizeTAChk.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				if (densityNormalizeTAChk.isSelected()){
+					densityFNABtn.setEnabled(true);
+					densityFNATxt.setEnabled(true);
+				}else{
+					densityFNABtn.setEnabled(false);
+					densityFNATxt.setEnabled(false);
+				}
+			}
+		});
+
+		
+		densityNormalizeTAChk.setBounds(10, 141, 358, 23);
+		panel_1.add(densityNormalizeTAChk);
+		
+		JLabel label_17 = new JLabel("(?)");
+		label_17.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, "This is suitable for analysis of Mariner transposon libraries. Instead of number of reads/insertions per\n"
+						+ "gene length the program will record number of reads/insertions per TA site within the gene.");
+			}
+		});
+		label_17.setToolTipText("Click me!");
+		label_17.setForeground(Color.BLUE);
+		label_17.setFont(new Font("Dialog", Font.PLAIN, 11));
+		label_17.setBounds(371, 145, 88, 14);
+		panel_1.add(label_17);
+		
+		JLabel label_18 = new JLabel("Select the 'FNA' File:");
+		label_18.setBounds(10, 175, 164, 14);
+		panel_1.add(label_18);
+		
+		densityFNATxt = new JTextField();
+		densityFNATxt.setEnabled(false);
+		densityFNATxt.setEditable(false);
+		densityFNATxt.setColumns(10);
+		densityFNATxt.setBounds(176, 172, 451, 20);
+		panel_1.add(densityFNATxt);
+		densityFNABtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				SelectFNA fna = new SelectFNA(info, AddMoreIndices.this, densityFNATxt);
+				
+				//Search for FNA
+				File folder = new File(AddMoreIndices.this.info.getPath());
+				File[] listOfFiles = folder.listFiles();
+
+				for (int i = 0; i < listOfFiles.length; i++) {
+					if (listOfFiles[i].isFile() && listOfFiles[i].getName().endsWith(".fna")) {
+						fna.setFNAPath(listOfFiles[i].getAbsolutePath());
+						break;
+					}
+				}
+				
+				AddMoreIndices.this.setVisible(false);
+			}
+		});
+		densityFNABtn.setEnabled(false);
+		
+		densityFNABtn.setToolTipText("Select a FNA file");
+		densityFNABtn.setBounds(637, 171, 89, 23);
+		panel_1.add(densityFNABtn);
+		
+		JPanel panel_3 = new JPanel();
+		tabbedPane.addTab("Add insertion counts", null, panel_3, null);
+		panel_3.setLayout(null);
+		
+		JLabel label_10 = new JLabel("Choose a library:");
+		label_10.setBounds(10, 35, 137, 14);
+		panel_3.add(label_10);
+		
+		countInsLibCombo.setToolTipText("Choose a library to use for adding datat to the table");
+		countInsLibCombo.setBounds(157, 32, 569, 20);
+		panel_3.add(countInsLibCombo);
+		
+		JLabel lblAdjustGeneStart_1 = new JLabel("Adjust gene start:");
+		lblAdjustGeneStart_1.setBounds(10, 63, 137, 14);
+		panel_3.add(lblAdjustGeneStart_1);
+		
+		countInsAdjStartTxt = new JTextField();
+		countInsAdjStartTxt.setToolTipText("You can also omit percent sign and use regular number");
+		countInsAdjStartTxt.setText("-5%");
+		countInsAdjStartTxt.setColumns(10);
+		countInsAdjStartTxt.setBounds(157, 60, 86, 20);
+		countInsAdjStartTxt.setInputVerifier(new PercentageInputVerifier(errorMsg2Lbl, countInsBtn));
+		panel_3.add(countInsAdjStartTxt);
+		
+		JLabel lblTest = new JLabel("Adjust gene end:");
+		lblTest.setBounds(350, 63, 137, 14);
+		panel_3.add(lblTest);
+		
+		countInsAdjEndTxt = new JTextField();
+		countInsAdjEndTxt.setToolTipText("You can also omit percent sign and use regular number");
+		countInsAdjEndTxt.setText("-20%");
+		countInsAdjEndTxt.setColumns(10);
+		countInsAdjEndTxt.setBounds(475, 60, 86, 20);
+		countInsAdjEndTxt.setInputVerifier(new PercentageInputVerifier(errorMsg2Lbl, countInsBtn));
+		panel_3.add(countInsAdjEndTxt);
+		
+		countInsBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				countIns();
+			}
+		});
+		countInsBtn.setBounds(637, 412, 89, 23);
+		panel_3.add(countInsBtn);
+		countInsPleaseWaitLbl.setIcon(new ImageIcon(AddMoreIndices.class.getResource("/resources/load.gif")));
+		
+		countInsPleaseWaitLbl.setBounds(10, 416, 177, 14);
+		panel_3.add(countInsPleaseWaitLbl);
+		
+		countInsUniqueInsertionRadio.setSelected(true);
+		countInsUniqueInsertionRadio.setBounds(10, 84, 281, 23);
+		panel_3.add(countInsUniqueInsertionRadio);
+		
+		countInsAllReadsRadio.setBounds(10, 110, 281, 23);
+		panel_3.add(countInsAllReadsRadio);
+		
+		JLabel label_2 = new JLabel("(?)");
+		label_2.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, ""
+						+ "This parameter automatically adjusts the start coordinates for all genes. To leave the gene start\n"
+						+ "coordinates as annotated, use zero. To shorten the gene at the 5th end by a specific number of\n"
+						+ "nucleotides use a negative number (for example, -50 will eliminate first 50 base pairs of each gene). The\n"
+						+ "value 50 or +50 would add 50 upstream nucleotides to the gene. Including the % sign will make the\n"
+						+ "adjustments relative to the gene length. For example, -5% will shorten the gene by 5% of its length at\n"
+						+ "the 5th end. Generally, you may want to exclude a short segment at the start of the gene to account for\n"
+						+ "possibly misannotated gene start sites.");
+			}
+		});
+		label_2.setToolTipText("Click me!");
+		label_2.setForeground(Color.BLUE);
+		label_2.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_2.setBounds(253, 63, 88, 14);
+		panel_3.add(label_2);
+		
+		JLabel label_4 = new JLabel("(?)");
+		label_4.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, ""
+						+ "This parameter automatically adjusts the end coordinates for all genes. To leave the gene end\n"
+						+ "coordinates as annotated, use zero. To shorten the gene at the 3th end by a specific number of\n"
+						+ "nucleotides use a negative number (for example, -50 will eliminate last 50 base pairs of each gene). The\n"
+						+ "value 50 or +50 would add 50 downstream nucleotides to the gene. Including the % sign will make the\n"
+						+ "adjustments relative to the gene length. For example, -20% will shorten the gene by 20% of its length at\n"
+						+ "the 3th end. Generaly, you may want to exclude the 3th end of the gene from the analysis because\n"
+						+ "transposon insertions near the end of the gene are less likely to be deletrious.");
+			}
+		});
+		label_4.setToolTipText("Click me!");
+		label_4.setForeground(Color.BLUE);
+		label_4.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_4.setBounds(571, 63, 88, 14);
+		panel_3.add(label_4);
+		
+		JLabel lblThisToolAdds = new JLabel("This tool adds a new data column with the count of insertions or read counts in each gene.");
+		lblThisToolAdds.setBounds(10, 11, 716, 14);
+		panel_3.add(lblThisToolAdds);
+		
+		errorMsg2Lbl.setForeground(Color.RED);
+		errorMsg2Lbl.setBounds(10, 391, 384, 14);
+		errorMsg2Lbl.setVisible(false);
+		panel_3.add(errorMsg2Lbl);
+
+		JPanel compareScrollPanel = new JPanel();
+		tabbedPane.addTab("Compare data", null, compareScrollPanel, null);
+		compareScrollPanel.setLayout(null);
+		
+		scrollPane.setBounds(10, 64, 716, 117);
+		compareScrollPanel.add(scrollPane);
+		
+		compareTable = new JTable();
+		scrollPane.setViewportView(compareTable);
+		
+		compareBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				compare();
+			}
+		});
+		compareBtn.setBounds(616, 407, 110, 23);
+		compareScrollPanel.add(compareBtn);
+		
+		JLabel lblMaximumInsertions = new JLabel("Maximum insertions:");
+		lblMaximumInsertions.setBounds(10, 192, 268, 14);
+		compareScrollPanel.add(lblMaximumInsertions);
+		
+		compareMaxInsTxt = new JTextField();
+		compareMaxInsTxt.setBounds(237, 189, 103, 20);
+		compareScrollPanel.add(compareMaxInsTxt);
+		compareMaxInsTxt.setColumns(10);
+		
+		JLabel label_12 = new JLabel("(?)");
+		label_12.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, "Maximum Insertions specifies a maximum number of insertions\n"
+						+ "If it is higher in any of the compared columns it is adjusted to this number");
+			}
+		});
+		label_12.setToolTipText("Click me!");
+		label_12.setForeground(Color.BLUE);
+		label_12.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_12.setBounds(350, 192, 88, 14);
+		compareScrollPanel.add(label_12);
+		
+		JLabel lblSelectColumn = new JLabel("Select column 1 for compare:");
+		lblSelectColumn.setBounds(10, 220, 310, 14);
+		compareScrollPanel.add(lblSelectColumn);
+		
+		JLabel lblSelectColumn_1 = new JLabel("Select column 2 for compare:");
+		lblSelectColumn_1.setBounds(10, 248, 310, 14);
+		compareScrollPanel.add(lblSelectColumn_1);
+		
+		columnOneCombo.setBounds(288, 220, 52, 20);
+		compareScrollPanel.add(columnOneCombo);
+		
+		columnTwoCombo.setBounds(288, 245, 52, 20);
+		compareScrollPanel.add(columnTwoCombo);
+		
+		compareWaitLbl.setIcon(new ImageIcon(AddMoreIndices.class.getResource("/resources/load.gif")));
+		compareWaitLbl.setBounds(10, 411, 112, 14);
+		compareScrollPanel.add(compareWaitLbl);
+		
+		JButton plotTwoColBtn = new JButton("Plot");
+		plotTwoColBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				plotColumns();
+			}
+		});
+		plotTwoColBtn.setBounds(372, 407, 110, 23);
+		compareScrollPanel.add(plotTwoColBtn);
+		
+		logPlotCheck.setBounds(450, 220, 171, 23);
+		compareScrollPanel.add(logPlotCheck);
+		
+		randomizePlotDataChk.setBounds(450, 248, 151, 23);
+		compareScrollPanel.add(randomizePlotDataChk);
+		
+		JXLabel lblNewLabel = new JXLabel("The 'Ratio' and 'Difference' buttons add a new column to the table that contains the ratio or difference of the values in two previously created; "
+				+ "the 'Plot' button plots data in two previously created columns.");
+		lblNewLabel.setBounds(10, 11, 716, 42);
+		lblNewLabel.setLineWrap(true);
+		compareScrollPanel.add(lblNewLabel);
+		
+		JLabel label_5 = new JLabel("(?)");
+		label_5.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(AddMoreIndices.this, 
+						  "This option adds a random number between 0.75 and 1.25 to each value. This could be\n"
+						+ "beneficial when plotting data where several genes often have the same values in both\n"
+						+ "compared columns. As a result, such genes will appear as a cloud of data points in\n"
+						+ "the plot rather than a single point.\n\n"
+						+ "This is intended to be used only with essentiality indices; do not check this box when \n"
+						+ "comparing insertion densities.");
+			}
+		});
+		label_5.setToolTipText("Click me!");
+		label_5.setForeground(Color.BLUE);
+		label_5.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_5.setBounds(605, 253, 88, 14);
+		compareScrollPanel.add(label_5);
+		
+		JButton btnRatio = new JButton("Ratio");
+		btnRatio.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				ratio();
+			}
+		});
+		btnRatio.setBounds(494, 406, 110, 25);
+		compareScrollPanel.add(btnRatio);
+	}
+
+	protected void plotDensities() {
+		
+		String item = (String) step2ColumnCombo.getSelectedItem();
+		
+		final String columnName = item.substring(item.indexOf("\t") + 1);
+		final int columnIndex = Integer.parseInt(item.substring(0, item.indexOf(":")));
+		final int averageBucket = Integer.parseInt(step2AverageTxt.getText());
+		
+		step2WaitLbl.setVisible(true);
+		step2PlotBtn.setEnabled(false);
+		
+		this.logPlot = logPlotCheck.isSelected();
+		
+		(new Thread(new Runnable() {
+			
+			@Override
+			public void run() {
+				
+				String tempTitle = "Table: " + tableName + ", Column: " + columnName + " (#" + columnIndex + "), Average densities per bucket: " + averageBucket;
+				
+				ChartPanel panel;
+				int numX = 0;
+				int numY = 0;
+
+				try {
+					panel = new ChartPanel(PlotData.plotInsertionDensities(new File(info.getPath() + tableName + ".table.xls"), columnName, columnIndex, tempTitle, averageBucket, info));
+					
+					String libName = columnName.substring(columnName.indexOf(": ") + 2);
+					BufferedReader br = new BufferedReader(new FileReader(new File(info.getPath() + libName + ".inspou")));
+					
+					String line = br.readLine();
+					while (line != null){
+						line = line.substring(line.indexOf("\t") + 1);
+						line = line.substring(line.indexOf("\t") + 1);
+						numX = numX + Integer.parseInt(line);
+						numY++;
+
+						line = br.readLine();
+					}
+					br.close();
+					
+				} catch (IOException e) {
+					logger.error("Some error while creating the plot!");
+					return;
+				}
+				
+				PlotViewer frame = new PlotViewer();
+				frame.hasChartListener = true;
+				frame.setPlotName(tempTitle);
+				frame.setVisible(true);
+				frame.addPlot(panel);
+				frame.plotInfo.setText(String.format("The library includes %d reads mapped to %d unique insertions", numX, numY));
+				
+				step2WaitLbl.setVisible(false);
+				step2PlotBtn.setEnabled(true);
+				initializeDensityInsertions();
+			}
+		})).start();
+		
+	}
+
+	protected void calcInsertionDensity() {
+		final String libraryName = (String) step2Combo.getSelectedItem(); 
+		final String adjStart = step2AdjustStart.getText();
+		final String adjEnd = step2AdjustEnd.getText();
+		final String fnaPath = densityFNATxt.getText();
+		final boolean normalizeTA = densityNormalizeTAChk.isSelected();
+		
+		if (normalizeTA && (fnaPath.equals("") || fnaPath == null)){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select the FNA file!");
+			return;
+		}
+		
+		countInsPleaseWaitLbl.setVisible(true);
+		countInsBtn.setEnabled(false);
+		
+		(new Thread(new Runnable() {
+			
+			@Override
+			public void run() {
+				try {
+					if (!normalizeTA){
+						if (AddColumns.calcInsertionDensity(libraryName, tableName, adjStart, adjEnd, step2UniqueRadio.isSelected(), info).compareTo(Messages.successMsg) == 0)
+							JOptionPane.showMessageDialog(AddMoreIndices.this, "Data added");
+					}else if (normalizeTA){
+						if (AddColumns.calcInsertionDensityTA(libraryName, tableName, adjStart, adjEnd, step2UniqueRadio.isSelected(), fnaPath, info).compareTo(Messages.successMsg) == 0)
+							JOptionPane.showMessageDialog(AddMoreIndices.this, "Data added");
+					}
+					else{
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "There was some problem, data was not added!!!", "Error", JOptionPane.ERROR_MESSAGE);
+					}
+					
+					countInsPleaseWaitLbl.setVisible(false);
+					countInsBtn.setEnabled(true);
+					initializeDensityInsertions();
+				} catch (IOException e) {
+					logger.error(e.getMessage());
+					return;
+				}
+			}
+		})).start();
+	}
+
+	private void plotColumns(){
+		
+		String firstCol = (String) columnOneCombo.getSelectedItem();
+		String secondCol = (String) columnTwoCombo.getSelectedItem();
+		
+		if (firstCol == null || firstCol.compareTo("") == 0){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select columns to compare.");
+			return;
+		}
+		
+		if (secondCol == null || secondCol.compareTo("") == 0){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select columns to compare.");
+			return;
+		}
+		
+		final int first = Integer.parseInt(firstCol);
+		final int second = Integer.parseInt(secondCol);
+		
+		if (first == second){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select different columns to compare.");
+			return;
+		}
+		
+		compareWaitLbl.setVisible(true);
+		compareBtn.setEnabled(false);
+		
+		this.logPlot = logPlotCheck.isSelected();
+		
+		(new Thread(new Runnable() {
+			
+			@Override
+			public void run() {
+				
+				String tempTitle = "";
+				if (!randomizePlotDataChk.isSelected())
+					tempTitle = tableName + ", Columns: " + first + " v.s. " + second;
+				else
+					tempTitle = tableName + ", Columns: " + first + " v.s. " + second + " (Randomized data)";
+				
+				ChartPanel panel;
+				PlotViewer frame = new PlotViewer();
+				try {
+					panel = new ChartPanel(PlotData.plotColumns(tableName, first, second, AddMoreIndices.this.logPlot, tempTitle, randomizePlotDataChk.isSelected(), info));
+					panel.addChartMouseListener(new MyChartMouseListener(frame.plotInfo));
+					frame.hasChartListener = true;
+				} catch (IOException e) {
+					logger.error("Some error while creating the plot!");
+					return;
+				}
+				
+				frame.setPlotName(tempTitle);
+				frame.setVisible(true);
+				frame.addPlot(panel);
+				
+				compareWaitLbl.setVisible(false);
+				compareBtn.setEnabled(true);
+				initializeCompare();
+			}
+		})).start();
+		
+	}
+	
+	private void ratio(){
+		String firstCol = (String) columnOneCombo.getSelectedItem();
+		String secondCol = (String) columnTwoCombo.getSelectedItem();
+		
+		if (firstCol == null || firstCol.compareTo("") == 0){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select columns to compare.");
+			return;
+		}
+		
+		if (secondCol == null || secondCol.compareTo("") == 0){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select columns to compare.");
+			return;
+		}
+		
+		final int first = Integer.parseInt(firstCol);
+		final int second = Integer.parseInt(secondCol);
+		if (first == second){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select different columns to compare.");
+			return;
+		}
+		
+		compareWaitLbl.setVisible(true);
+		compareBtn.setEnabled(false);
+		
+		(new Thread(new Runnable() {
+			
+			@Override
+			public void run() {
+				try {
+					double maxIns = 0;
+					if (compareMaxInsTxt.getText() != null && !compareMaxInsTxt.getText().equals("")){
+						maxIns = Double.parseDouble(compareMaxInsTxt.getText()); 
+					}
+					
+					if (AddColumns.compareColumnsRatio(tableName, first, second, maxIns, info).compareTo(Messages.successMsg) == 0){
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "Data added");
+					}else{
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "The data could not be written to the table.\n"
+								+ "Check to see if they are not in use by other programs!", "Error", JOptionPane.ERROR_MESSAGE);
+					}
+					
+					compareWaitLbl.setVisible(false);
+					compareBtn.setEnabled(true);
+					initializeCompare();
+				} catch (IOException e) {
+					logger.error(e.getMessage());
+					return;
+				}catch (NumberFormatException e) {
+					JOptionPane.showMessageDialog(AddMoreIndices.this, "Please enter valid numbers for the highlighted fields.");
+					compareWaitLbl.setVisible(false);
+					compareBtn.setEnabled(true);
+					return;
+				}
+			}
+		})).start();
+	}
+	
+	private void compare(){
+		
+		String firstCol = (String) columnOneCombo.getSelectedItem();
+		String secondCol = (String) columnTwoCombo.getSelectedItem();
+		
+		if (firstCol == null || firstCol.compareTo("") == 0){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select columns to compare.");
+			return;
+		}
+		
+		if (secondCol == null || secondCol.compareTo("") == 0){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select columns to compare.");
+			return;
+		}
+		
+		final int first = Integer.parseInt(firstCol);
+		final int second = Integer.parseInt(secondCol);
+		if (first == second){
+			JOptionPane.showMessageDialog(AddMoreIndices.this, "Please select different columns to compare.");
+			return;
+		}
+		
+		compareWaitLbl.setVisible(true);
+		compareBtn.setEnabled(false);
+		
+		(new Thread(new Runnable() {
+			
+			@Override
+			public void run() {
+				try {
+					double maxIns = 0;
+					if (compareMaxInsTxt.getText() != null && !compareMaxInsTxt.getText().equals("")){
+						maxIns = Double.parseDouble(compareMaxInsTxt.getText()); 
+					}
+					
+					if (AddColumns.compareColumnsDiff(tableName, first, second, maxIns, info).compareTo(Messages.successMsg) == 0){
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "Data added");
+					}else{
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "The data could not be written to the table.\n"
+								+ "Check to see if they are not in use by other programs!", "Error", JOptionPane.ERROR_MESSAGE);
+					}
+					
+					compareWaitLbl.setVisible(false);
+					compareBtn.setEnabled(true);
+					initializeCompare();
+				} catch (IOException e) {
+					logger.error(e.getMessage());
+					return;
+				}catch (NumberFormatException e) {
+					JOptionPane.showMessageDialog(AddMoreIndices.this, "Please enter valid numbers for the highlighted fields.");
+					compareWaitLbl.setVisible(false);
+					compareBtn.setEnabled(true);
+					return;
+				}
+			}
+		})).start();
+		
+	}
+	
+	private void countIns(){
+		
+		final String libraryName = (String) countInsLibCombo.getSelectedItem(); 
+		final String adjStart = countInsAdjStartTxt.getText();
+		final String adjEnd = countInsAdjEndTxt.getText();
+		
+		countInsPleaseWaitLbl.setVisible(true);
+		countInsBtn.setEnabled(false);
+		
+		(new Thread(new Runnable() {
+			
+			@Override
+			public void run() {
+				try {
+					if (AddColumns.countInsertions(libraryName, tableName, adjStart, adjEnd, countInsUniqueInsertionRadio.isSelected(), info).compareTo(Messages.successMsg) == 0){
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "Data added");
+					}else{
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "There was some problem, data was not added!!!", "Error", JOptionPane.ERROR_MESSAGE);
+					}
+					
+					countInsPleaseWaitLbl.setVisible(false);
+					countInsBtn.setEnabled(true);
+				} catch (IOException e) {
+					logger.error(e.getMessage());
+					e.printStackTrace();
+					return;
+				}
+			}
+		})).start();
+		
+	}
+	
+	private void initializeProgressBar(){		
+		progressBar.setMinimum(0);
+		progressBar.setMaximum(100);
+		
+		progressBar.setValue(0);
+		progressBar.setVisible(false);
+	}
+	
+	private void addBtnAction(){
+
+		final String libraryName = (String) addLibraryCombo.getSelectedItem();
+		final String adjStart = adjustStartTxt.getText();
+		final String adjEnd = adjustEndTxt.getText();
+		final int seqLen = info.getSequenceLen();
+
+		initializeProgressBar();
+		lblPleaseWait.setVisible(true);
+		progressBar.setVisible(true);
+		addMoreColumnsBtn.setEnabled(false);
+		
+		(new Thread(new Runnable() {
+			@Override
+			public void run() {
+				try {
+					int windowLen = 0;
+					int step = 0;
+					try{
+						windowLen = Integer.parseInt(addWinLenTxt.getText());
+						step = Integer.parseInt(addStepTxt.getText());
+					}catch(NumberFormatException e){
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "Please enter valid numbers for the highlighted fields.");
+						progressBar.setVisible(false);
+						lblPleaseWait.setVisible(false);
+						addMoreColumnsBtn.setEnabled(true);
+						return;
+					}
+					
+					if (AddColumns.add(libraryName, tableName, windowLen, step, adjStart, adjEnd, seqLen, newDataUniqueInsertionRadio.isSelected(), progressBar, info).compareTo(Messages.successMsg) == 0){
+						progressBar.setVisible(false);
+						lblPleaseWait.setVisible(false);
+						addMoreColumnsBtn.setEnabled(true);
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "Data added");
+					}else{
+						JOptionPane.showMessageDialog(AddMoreIndices.this, "There was some problem, data was not added!!!", "Error", JOptionPane.ERROR_MESSAGE);
+					}
+
+				} catch (IOException e) {
+					logger.error(e.getMessage());
+					return;
+				}
+			}
+		})).start();
+		
+	}
+	
+	private void initializeAddPanel(){
+
+		//Initializing Libraries ComboBox
+		BufferedReader br = null;
+
+		if(addLibraryCombo != null){
+			addLibraryCombo.removeAllItems();
+		}
+
+		try{
+			br = new BufferedReader(new FileReader(info.getFile()));
+
+			String line = br.readLine();
+			br.readLine();
+			br.readLine();
+
+			while(line != null){
+				line = br.readLine();
+
+				if (line != null)
+					addLibraryCombo.addItem(line.substring(0, line.length() - 6));
+
+				line = br.readLine();
+				line = br.readLine();
+				line = br.readLine();
+			}
+
+			br.close();
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return;
+		}finally{
+			try{
+				br.close();
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return;
+			}
+		}
+
+		try{
+			File winInfo = new File(info.getPath() + addLibraryCombo.getSelectedItem() + ".data");
+			if (winInfo.exists()){
+				br = new BufferedReader(new FileReader(winInfo));
+				String line = br.readLine();
+				int tempLen = Integer.parseInt(line.substring(line.indexOf("=") + 2, line.length()));
+				line = br.readLine();
+				int tempStep = Integer.parseInt(line.substring(line.indexOf("=") + 2, line.length()));
+				br.close();
+				
+				addWinLenTxt.setText(tempLen + "");
+				addStepTxt.setText(tempStep + "");
+				
+			}
+		}catch (IOException e){
+			logger.fatal(e.getMessage());
+		}
+		
+		addSeqLenTxt.setText(info.getSequenceLen() + "");
+		initializeProgressBar();
+	}
+}
\ No newline at end of file
diff --git a/src/GUI/ExtendedPlotViewer.java b/src/GUI/ExtendedPlotViewer.java
new file mode 100644
index 0000000..9a91c6f
--- /dev/null
+++ b/src/GUI/ExtendedPlotViewer.java
@@ -0,0 +1,306 @@
+package GUI;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.EtchedBorder;
+
+import org.jfree.chart.ChartPanel;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.data.Range;
+
+import essgenes.PlotData;
+import essgenes.ProjectInfo;
+import javax.swing.ImageIcon;
+
+ at SuppressWarnings("serial")
+public class ExtendedPlotViewer extends JFrame {
+
+	private JPanel contentPane;
+	private JPanel plotPanel = new JPanel();
+	private JTextField xStartTxt;
+	private JTextField xEndTxt;
+	private JTextField yStartTxt;
+	private JTextField yEndTxt;
+	public JTextField winLenTxt;
+	public JTextField winStepTxt;
+	private JFrame parent = null;
+	
+	private String dataFile;
+	private Integer currentWinLen;
+	private Integer currentWinStep;
+	private boolean countOnlyUnique;
+	private ProjectInfo projectInfo;
+	private JLabel waitLbl = new JLabel("Please wait...");
+	
+	/**
+	 * Create the frame.
+	 */
+	public ExtendedPlotViewer(JFrame parent) {
+		this.parent = parent;
+		
+		setResizable(false);
+		setTitle("Plot");
+		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+		
+		addWindowListener(new WindowAdapter() {
+			@Override
+			public void windowClosing(WindowEvent arg0) {
+				checkIfApplied();
+			}
+		});
+		
+		setBounds(100, 100, 869, 674);
+		contentPane = new JPanel();
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		setContentPane(contentPane);
+		contentPane.setLayout(null);
+		
+		plotPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
+		plotPanel.setBounds(10, 36, 843, 480);
+		contentPane.add(plotPanel);
+		
+		JLabel lblResultPlot = new JLabel("Result plot:");
+		lblResultPlot.setBounds(10, 11, 96, 14);
+		contentPane.add(lblResultPlot);
+		
+		JLabel lblChangePlotRanges = new JLabel("Change plot ranges:");
+		lblChangePlotRanges.setBounds(10, 527, 216, 14);
+		contentPane.add(lblChangePlotRanges);
+		
+		JLabel lblXAxisStart = new JLabel("X Axis start:");
+		lblXAxisStart.setBounds(20, 552, 111, 14);
+		contentPane.add(lblXAxisStart);
+		
+		xStartTxt = new JTextField();
+		xStartTxt.setText("0.0");
+		xStartTxt.setBounds(140, 549, 86, 20);
+		contentPane.add(xStartTxt);
+		xStartTxt.setColumns(10);
+		
+		JLabel lblXAxisEnd = new JLabel("X Axis end:");
+		lblXAxisEnd.setBounds(20, 580, 111, 14);
+		contentPane.add(lblXAxisEnd);
+		
+		xEndTxt = new JTextField();
+		xEndTxt.setText("2000.0");
+		xEndTxt.setColumns(10);
+		xEndTxt.setBounds(140, 577, 86, 20);
+		contentPane.add(xEndTxt);
+		
+		JLabel lblYAxisStart = new JLabel("Y Axis start:");
+		lblYAxisStart.setBounds(283, 555, 111, 14);
+		contentPane.add(lblYAxisStart);
+		
+		yStartTxt = new JTextField();
+		yStartTxt.setText("0.0");
+		yStartTxt.setColumns(10);
+		yStartTxt.setBounds(403, 552, 86, 20);
+		contentPane.add(yStartTxt);
+		
+		JLabel lblYAxisEnd = new JLabel("Y Axis end:");
+		lblYAxisEnd.setBounds(283, 577, 111, 14);
+		contentPane.add(lblYAxisEnd);
+		
+		yEndTxt = new JTextField();
+		yEndTxt.setText("300.0");
+		yEndTxt.setColumns(10);
+		yEndTxt.setBounds(403, 574, 86, 20);
+		contentPane.add(yEndTxt);
+		
+		JButton replotBtn = new JButton("Re-Plot");
+		replotBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				replot();
+			}
+		});
+		replotBtn.setBounds(591, 612, 89, 23);
+		contentPane.add(replotBtn);
+		
+		JLabel lblWindowLength = new JLabel("Window length:");
+		lblWindowLength.setBounds(535, 555, 111, 14);
+		contentPane.add(lblWindowLength);
+		
+		winLenTxt = new JTextField();
+		winLenTxt.setText("0.0");
+		winLenTxt.setColumns(10);
+		winLenTxt.setBounds(655, 552, 86, 20);
+		contentPane.add(winLenTxt);
+		
+		JLabel lblWindowStep = new JLabel("Window step:");
+		lblWindowStep.setBounds(535, 577, 111, 14);
+		contentPane.add(lblWindowStep);
+		
+		winStepTxt = new JTextField();
+		winStepTxt.setText("0.0");
+		winStepTxt.setColumns(10);
+		winStepTxt.setBounds(655, 574, 86, 20);
+		contentPane.add(winStepTxt);
+		
+		JButton applyBtn = new JButton("Apply and Close");
+		applyBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				apply();
+			}
+		});
+		applyBtn.setBounds(690, 612, 163, 23);
+		contentPane.add(applyBtn);
+		
+		waitLbl.setIcon(new ImageIcon(ExtendedPlotViewer.class.getResource("/resources/load.gif")));
+		waitLbl.setBounds(10, 616, 183, 14);
+		waitLbl.setVisible(false);
+		
+		contentPane.add(waitLbl);
+	}
+	
+	private void checkIfApplied(){
+		
+		if (!((MainFrame)parent).checkIfApplied(Integer.parseInt(winLenTxt.getText()), Integer.parseInt(winStepTxt.getText()))){
+			int result = JOptionPane.showConfirmDialog(this, "The new values have not been applied. \nDo you want to keep the changes?");
+			if (result == JOptionPane.YES_OPTION){
+				((MainFrame)parent).setWinInfoAndSave(Integer.parseInt(winLenTxt.getText()), Integer.parseInt(winStepTxt.getText()));
+				this.setVisible(false);
+				this.dispose();
+			}else if (result == JOptionPane.NO_OPTION){
+				this.setVisible(false);
+				this.dispose();
+			}else{
+				return;
+			}
+		}else{
+			this.setVisible(false);
+			this.dispose();
+		}
+		
+	}
+	
+	private void apply(){
+		((MainFrame)parent).setWinInfoAndSave(Integer.parseInt(winLenTxt.getText()), Integer.parseInt(winStepTxt.getText()));
+		this.setVisible(false);
+		this.dispose();
+	}
+	
+	public void replot(){
+
+		waitLbl.setVisible(true);
+		
+		(new Thread(new Runnable() {
+			@Override
+			public void run() {
+				int newWinLen = Integer.parseInt(winLenTxt.getText());
+				int newWinStep = Integer.parseInt(winStepTxt.getText());
+
+				final String title;
+				if (countOnlyUnique){
+					String temp = String.format("Library Name: %s (Counting unique insertions) | Window Length: %d | Window Steps: %d", dataFile, newWinLen, newWinStep);
+					title = temp;
+				} else{
+					String temp = String.format("Library Name: %s (Counting all reads) | Window Length: %d | Window Steps: %d", dataFile, newWinLen, newWinStep);
+					title = temp;
+				}
+
+				if (newWinLen != currentWinLen || newWinStep != currentWinStep){
+					ChartPanel panel = new ChartPanel(PlotData.plotData(dataFile, newWinLen, newWinStep, title, projectInfo, countOnlyUnique));
+					ExtendedPlotViewer.this.addPlot(panel);
+					currentWinLen = newWinLen;
+					currentWinStep = newWinStep;
+
+				}else{
+					Double xStart = null;
+
+					if (xStartTxt.getText() != null || xStartTxt.getText().compareTo("") != 0){
+						xStart = Double.parseDouble(xStartTxt.getText());
+					}
+
+					Double xEnd = null;
+
+					if (xEndTxt.getText() != null || xEndTxt.getText().compareTo("") != 0){
+						xEnd = Double.parseDouble(xEndTxt.getText());
+					}
+
+					Double yStart = null;
+
+					if (yStartTxt.getText() != null || yStartTxt.getText().compareTo("") != 0){
+						yStart = Double.parseDouble(yStartTxt.getText());
+					}
+
+					Double yEnd = null;
+
+					if (yEndTxt.getText() != null || yEndTxt.getText().compareTo("") != 0){
+						yEnd = Double.parseDouble(yEndTxt.getText());
+					}
+
+					ChartPanel panel = (ChartPanel) plotPanel.getComponent(0);
+					JFreeChart chart = panel.getChart();
+					XYPlot plot = chart.getXYPlot();
+
+					if (xStart != null && xEnd != null){
+						plot.getDomainAxis().setRange(xStart, xEnd);
+					}
+
+					if (yStart != null && yEnd != null){
+						plot.getRangeAxis().setRange(yStart, yEnd);
+					}
+				}
+				
+				waitLbl.setVisible(false);
+			}
+		})).start();
+		
+		JOptionPane.showMessageDialog(this, "The replotting process might take some time. \nPlease be patient.");
+		
+	}
+	
+	public void addPlot(ChartPanel chart){
+		plotPanel.setLayout(new BorderLayout());
+		plotPanel.add(chart, BorderLayout.CENTER);
+		plotPanel.validate();
+		
+		//Initializing the default values for ranges
+		JFreeChart chart1 = chart.getChart();
+		XYPlot plot = chart1.getXYPlot();
+		Range range = plot.getDomainAxis().getRange();
+		xStartTxt.setText(range.getLowerBound() + "");
+		xEndTxt.setText(range.getUpperBound() + "");
+		range = plot.getRangeAxis().getRange();
+		yStartTxt.setText(range.getLowerBound() + "");
+		yEndTxt.setText(range.getUpperBound() + "");
+	}
+	
+	public void setPlotName(String title){
+		setTitle(title);
+	}
+
+	public void setWinInfo(Integer winLen, Integer winStep) {
+		winLenTxt.setText(winLen + "");
+		winStepTxt.setText(winStep + "");
+	}
+
+	public void setDataFile(String dataFile) {
+		this.dataFile = dataFile;
+	}
+
+	public void setCurrentInfo(Integer winLen, Integer winStep) {
+		currentWinLen = winLen;
+		currentWinStep = winStep;
+	}
+
+	public void setIfSelected(boolean selected) {
+		this.countOnlyUnique = selected;
+	}
+
+	public void setProjectInfo(ProjectInfo projectInfo) {
+		this.projectInfo = projectInfo;
+	}
+}
diff --git a/src/GUI/LegalDisclaimer.java b/src/GUI/LegalDisclaimer.java
new file mode 100644
index 0000000..2005542
--- /dev/null
+++ b/src/GUI/LegalDisclaimer.java
@@ -0,0 +1,72 @@
+package GUI;
+
+import java.awt.Toolkit;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.border.EmptyBorder;
+
+import org.jdesktop.swingx.JXLabel;
+
+ at SuppressWarnings("serial")
+public class LegalDisclaimer extends JFrame {
+
+	private JPanel contentPane;
+	JXLabel lblNewLabel = new JXLabel("New label");
+	
+	public LegalDisclaimer() {
+		setTitle("Legal Disclaimer");
+		setIconImage(Toolkit.getDefaultToolkit().getImage(LegalDisclaimer.class.getResource("/resources/legaldisclaimer.png")));
+		setResizable(false);
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		setBounds(100, 100, 722, 220);
+		contentPane = new JPanel();
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		setContentPane(contentPane);
+		contentPane.setLayout(null);
+		setLocationRelativeTo(null);
+		
+		lblNewLabel.setBounds(120, 11, 558, 116);
+		contentPane.add(lblNewLabel);
+		
+		String text = String.format("By using this software, you agree to the following:");
+		text = String.format("%s\n\n    (a) This software is distributed \"as is\" with no warranty or support, without even the implied warranty of", text);
+		text = String.format("%s\n      merchantability or fitness for a particular purpose.", text);
+		text = String.format("%s\n\n    (b) The authors shall not be liable for any claim, damages, or other liability in connection with this software.", text);
+		
+		lblNewLabel.setText(text);
+		lblNewLabel.setLineWrap(true);
+		
+		JLabel lblNewLabel_1 = new JLabel("");
+		lblNewLabel_1.setIcon(new ImageIcon(LegalDisclaimer.class.getResource("/resources/legaldisclaimer.png")));
+		lblNewLabel_1.setBounds(10, 11, 100, 100);
+		contentPane.add(lblNewLabel_1);
+		
+		JButton btnNewButton = new JButton("Agree");
+		btnNewButton.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				WorkspaceChooser ws = new WorkspaceChooser();
+				ws.setVisible(true);
+				
+				LegalDisclaimer.this.setVisible(false);
+				LegalDisclaimer.this.dispose();
+			}
+		});
+		btnNewButton.setBounds(617, 153, 89, 23);
+		contentPane.add(btnNewButton);
+		
+		JButton btnCancel = new JButton("Cancel");
+		btnCancel.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				System.exit(0);
+			}
+		});
+		btnCancel.setBounds(517, 153, 89, 23);
+		contentPane.add(btnCancel);
+	}
+}
diff --git a/src/GUI/MainFrame.java b/src/GUI/MainFrame.java
new file mode 100644
index 0000000..caa5e5c
--- /dev/null
+++ b/src/GUI/MainFrame.java
@@ -0,0 +1,4050 @@
+package GUI;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Desktop;
+import java.awt.Font;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.nio.channels.FileChannel;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Random;
+
+import javax.swing.ButtonGroup;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JSeparator;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.math3.util.Pair;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.log4j.Logger;
+import org.jdesktop.swingx.JXLabel;
+import org.jfree.chart.ChartPanel;
+
+import CustomGUIComponent.IntegerInputVerifier;
+import essgenes.Messages;
+import essgenes.MyFileUtil;
+import essgenes.PlotData;
+import essgenes.PrepareFiles;
+import essgenes.ProjectInfo;
+import essgenes.StatisticsHelper;
+
+ at SuppressWarnings("serial")
+public class MainFrame extends JFrame {
+	static int dx = 1;
+	public static final String ProgTitle = "Tn-seq explorer";
+	public static final String ProgVersion = "v1.5";
+
+	private JButton bowtieSamCreateBtn = new JButton("Create SAM file");
+	private boolean if_initialize_step_1 = true;
+	private JLabel label_10 = new JLabel("(?)");
+	private JLabel lblReads = new JLabel("reads.");
+	private JButton btnAnotherPlot = new JButton("Distribution of reads per unique insertion");
+	private JLabel lblWindowLength = new JLabel("Window length:");
+	private JLabel lblRemoveUniqueInsertions = new JLabel("Remove unique insertions with no more than");
+	private JLabel errorMsgLbl = new JLabel("Please enter a valid Integer value in the red fields.");
+	private JButton applySequenceBtn = new JButton("Apply");
+	private JLabel lblPleaseEnterAn = new JLabel("Please enter a valid Integer value.");
+	private JLabel winlenLbl = new JLabel("Testing Winlen = 500");
+	private JButton btnOptimal = new JButton("Recommend optimal Window Length");
+	private JLabel sequenceLengthLbl = new JLabel("0");
+	private JTextField sequenceLenTxt;
+	private JLabel libraryCountLbl = new JLabel("0");
+	private JTextField samFilePathTxt;
+	private JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
+	private JButton browseForSamBtn = new JButton("Browse");
+	private JButton extractInsBtn = new JButton("Extract");
+	private JButton cancelLibSaveBtn = new JButton("Clear the form");
+	private JLabel extractInsLbl = new JLabel("Extract insertion positions from the \"SAM\" file");
+	private JLabel sortUniLbl = new JLabel("Sort unique insertions by the number of reads");
+	private JLabel sortInsLbl = new JLabel("Sort the extracted insertion positions");
+	private JLabel countUniLbl = new JLabel("Count unique insertions and sort by position");
+	private JButton removeLibBtn = new JButton("Remove");
+	private JButton renameLibBtn = new JButton("Rename");
+	private JComboBox<String> libraryComboBox = new JComboBox<String>();
+	private JLabel loadingLbl = new JLabel("");
+	private JTextField pttFileTxt;
+	private JTextField rntFileTxt;
+	private final ButtonGroup buttonGroup = new ButtonGroup();
+	private JComboBox<String> ftpFirstLevelCombo = new JComboBox<String>();
+	private JComboBox<String> ftpSecondLevelCombo = new JComboBox<String>();
+	private JButton downloadBtn = new JButton("Download");
+	private JButton pttBrowseBtn = new JButton("Browse");
+	private JButton rntBrowseBtn = new JButton("Browse");
+	private JButton btnPrepareGeneFile = new JButton("Prepare gene file");
+	private JRadioButton ownRadioBtn = new JRadioButton("Use previously downloaded files from NCBI");
+	private JRadioButton databaseRadioBtn = new JRadioButton("Download annotation from NCBI FTP server");
+	private JLabel geneFileNameLbl = new JLabel("NONE");
+	private JComboBox<String> dataTableCombo = new JComboBox<String>();
+	private JButton dataTableRenameBtn = new JButton("Rename");
+	private JButton dataTableRemoveBtn = new JButton("Remove");
+	private JButton openAsSpreadsheetBtn = new JButton("Open as spreadsheet");
+	private JButton addNewDataTableBtn = new JButton("Create new");
+	private JButton replaceXlsBtn = new JButton("Replace");
+	private JLabel dataTableCountLbl = new JLabel("0");
+	private JLabel doneLbl1 = new JLabel("");
+	private JLabel doneLbl2 = new JLabel("");
+	private JLabel doneLbl3 = new JLabel("");
+	private JLabel doneLbl4 = new JLabel("");
+	private JButton tableCancelChangeBtn = new JButton("Cancel");
+	private JRadioButton imgRadioBtn = new JRadioButton("Use previously downloaded file from IMG");
+	private JTextField imgFileTxt;
+	private JButton imgBrowseBtn = new JButton("Browse");
+	private JComboBox<String> scaffoldCombo = new JComboBox<String>();
+	private JRadioButton alreadyInstalledRadio = new JRadioButton("Already installed");
+	private JRadioButton useScriptsRadio = new JRadioButton("Use the shell scripts to install them");
+	private JButton bwaInstallBtn = new JButton("Install BWA (v0.7.5a)");	
+	private JLabel infoLbl = new JLabel("* You have to provide the chromosome length and gene annotation to start a new project.");
+	private JComboBox<String> plotLibraryCombo = new JComboBox<String>();
+	private JTextField winLenTxt;
+	private JTextField winStepTxt;
+	private JButton plotBtn = new JButton("Plot");
+	private JLabel plotWaitLbl = new JLabel("Please wait...");
+	private JButton addNewIndicesBtn = new JButton("Add new data to the selected table");
+	private JButton remoteHelpBtn = new JButton("Create SAM file manually");
+	private JButton maxNumInsBtn = new JButton("Find essential regions");
+	private JRadioButton countOnlyUniqueRadio = new JRadioButton("Count only unique insertions");
+	private JRadioButton countAllReadsRadio = new JRadioButton("Count all sequence reads");
+
+	protected ProjectInfo projectInfo = new ProjectInfo();
+	private Logger logger = Logger.getLogger(MainFrame.class.getName());
+	private boolean hasSeqNum = false;
+	private boolean hasGeneFile = false;
+	private JTextField fastqFilePath;
+	private JTextField newSamNameTxt;
+	private JTextField samFilePath;
+	private JTextField maxNumInsTxt;
+	private Thread second_thread = null;
+	private JTextField removeUniqueInsertionsTxt;
+	private JTextField bowtieFastqTxt;
+	private JTextField bowtieFnaTxt;
+	private JTextField bowtieSamLocTxt;
+	private JTextField bowtieSamFilenameTxt;
+	private JTextField fnaFilePath;
+	private JTextField bowtieMinScore;
+
+	/**
+	 * Create the frame.
+	 */
+	public MainFrame(String projectPath) {
+		setResizable(false);
+		this.projectInfo.setPath(projectPath);
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		setBounds(100, 100, 859, 732);
+		setLocationRelativeTo(null);	
+		getContentPane().setLayout(null);
+
+		tabbedPane.setBounds(12, 13, 828, 659);
+		getContentPane().add(tabbedPane);
+
+		tabbedPane.addChangeListener(new ChangeListener() {
+			@Override
+			public void stateChanged(ChangeEvent arg0) {
+
+				int selectedTab = tabbedPane.getSelectedIndex();
+
+				if (selectedTab == 0){
+
+				}
+
+				if (selectedTab == 1){
+					initiateLibraryComboBox();
+				}
+
+				if(selectedTab == 2){
+					initiateDataTablesComboBox();
+				}
+
+				if(selectedTab == 3){
+					initializeBWAPanel();
+				}
+
+				if (selectedTab == 4){
+					initializeBowtiePanel();
+				}
+
+				String OSName = System.getProperty("os.name");
+				if (!(OSName.contains("windows") || OSName.contains("Windows"))){
+					Point p = MainFrame.this.getLocation();
+					p.translate(dx, 0);
+					dx *= -1;
+					MainFrame.this.setLocation(p);
+				}
+			}
+		});
+
+		ButtonGroup numberOfReads = new ButtonGroup();
+
+		JPanel panelMain = new JPanel();
+		tabbedPane.addTab("Main", null, panelMain, null);
+		panelMain.setLayout(null);
+
+		JLabel lblSequenceLength = new JLabel("Sequence Length (bp):");
+		lblSequenceLength.setFont(new Font("Tahoma", Font.PLAIN, 16));
+		lblSequenceLength.setBounds(12, 31, 212, 20);
+		panelMain.add(lblSequenceLength);
+
+		sequenceLenTxt = new JTextField();
+		sequenceLenTxt.addFocusListener(new FocusAdapter() {
+			@Override
+			public void focusGained(FocusEvent arg0) {
+				highlightAllTheText((JTextField) arg0.getComponent());
+			}
+		});
+		sequenceLenTxt.setToolTipText("Enter sequence length to be used in this project");
+		sequenceLenTxt.setBounds(231, 33, 150, 22);
+		panelMain.add(sequenceLenTxt);
+		sequenceLenTxt.setColumns(10);
+
+		sequenceLenTxt.setInputVerifier(new IntegerInputVerifier(lblPleaseEnterAn));
+
+		applySequenceBtn.setToolTipText("Apply the entered sequence length");
+		applySequenceBtn.setFont(new Font("Tahoma", Font.BOLD, 13));
+		applySequenceBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				applySequenceNumber();
+			}
+		});
+		applySequenceBtn.setBounds(391, 31, 97, 25);
+		panelMain.add(applySequenceBtn);
+
+		JSeparator separator = new JSeparator();
+		separator.setBounds(0, 62, 823, 2);
+		panelMain.add(separator);
+
+		JLabel lblProjectInformation = new JLabel("Project Information:");
+		lblProjectInformation.setFont(new Font("Tahoma", Font.PLAIN, 15));
+		lblProjectInformation.setBounds(12, 550, 144, 20);
+		panelMain.add(lblProjectInformation);
+
+		JLabel lblLibrariesCount = new JLabel("Libraries count:");
+		lblLibrariesCount.setFont(new Font("Tahoma", Font.PLAIN, 16));
+		lblLibrariesCount.setBounds(166, 555, 163, 22);
+		panelMain.add(lblLibrariesCount);
+
+		libraryCountLbl.setFont(new Font("Tahoma", Font.PLAIN, 15));
+		libraryCountLbl.setBounds(317, 550, 51, 33);
+		panelMain.add(libraryCountLbl);
+
+		JLabel lblDataTablesCount = new JLabel("Data tables count:");
+		lblDataTablesCount.setFont(new Font("Tahoma", Font.PLAIN, 16));
+		lblDataTablesCount.setBounds(166, 592, 163, 22);
+		panelMain.add(lblDataTablesCount);
+
+		dataTableCountLbl.setFont(new Font("Tahoma", Font.PLAIN, 15));
+		dataTableCountLbl.setBounds(317, 587, 51, 33);
+		panelMain.add(dataTableCountLbl);
+
+		ftpFirstLevelCombo.setBounds(12, 110, 695, 22);
+
+		panelMain.add(ftpFirstLevelCombo);
+		ftpSecondLevelCombo.setEnabled(false);
+
+		ftpSecondLevelCombo.setBounds(12, 145, 695, 22);
+		panelMain.add(ftpSecondLevelCombo);
+		downloadBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+
+				String temp = (String) ftpSecondLevelCombo.getSelectedItem();
+				temp = temp.substring(temp.indexOf("(") + 1);
+				temp = temp.substring(0, temp.indexOf(")"));
+				temp = temp.replaceAll(" bp", "");
+
+				int tempInt = Integer.parseInt(temp);
+				if (projectInfo.getSequenceLen() != 0 && projectInfo.getSequenceLen() != tempInt){
+
+					String msg = String.format("The sequence length in GenBank is %d.\nDo you want to use the GenBank length or the length you supplied manually?", tempInt);
+					int answer = JOptionPane.showOptionDialog(MainFrame.this, 
+							msg, 
+							"Warning", 
+							JOptionPane.YES_NO_OPTION, 
+							JOptionPane.WARNING_MESSAGE, 
+							null, 
+							new String[]{"GenBank", "Manual"}, // this is the array
+							"default");
+
+					if (answer == JOptionPane.YES_OPTION){
+						sequenceLenTxt.setText(tempInt + "");
+						applySequenceNumber();
+
+					}else{
+						//Do Nothing
+					}
+
+				}else if (projectInfo.getSequenceLen() == 0 && projectInfo.getSequenceLen() != tempInt){
+					sequenceLenTxt.setText(tempInt + "");
+					applySequenceNumber();
+				}
+
+				downloadBtn.setText("Downloading");
+
+				(new Thread(new Runnable(){
+					@Override
+					public void run() {
+						FTPClient ftp = new FTPClient();
+						try {
+							ftp.connect("ftp.ncbi.nih.gov");
+							ftp.enterLocalPassiveMode();
+							ftp.login("anonymous", "");
+							String ftpDir = "/genomes/archive/old_genbank/Bacteria/" + ftpFirstLevelCombo.getSelectedItem() + "/";
+							FTPFile[] files = ftp.listFiles(ftpDir);
+
+							for (FTPFile t : files){
+								String fileName = (String)ftpSecondLevelCombo.getSelectedItem();
+								fileName = fileName.substring(0, fileName.indexOf(":"));
+
+								if(t.getName().contains(fileName)){
+									if(t.getName().endsWith("ptt")){
+										File pttTemp = new File(projectInfo.getPath() + t.getName());
+										FileOutputStream fos = new FileOutputStream(pttTemp);
+										ftp.retrieveFile(ftpDir + t.getName(), fos);
+										pttFileTxt.setText(pttTemp.getAbsolutePath());
+									}else if(t.getName().endsWith("rnt")){
+										File rntTemp = new File(projectInfo.getPath() + t.getName());
+										FileOutputStream fos = new FileOutputStream(rntTemp);
+										ftp.retrieveFile(ftpDir + t.getName(), fos);
+										rntFileTxt.setText(rntTemp.getAbsolutePath());
+									}
+
+								}
+							}
+
+							downloadBtn.setText("Download");
+							downloadBtn.setEnabled(true);
+							ftpFirstLevelCombo.setEnabled(true);
+							ftpSecondLevelCombo.setEnabled(true);
+
+						} catch (IOException e) {
+							logger.error(e.getMessage());
+							return;
+						}
+
+						prepareGeneFile();
+
+						int answ = JOptionPane.showConfirmDialog(MainFrame.this, "Also download the .fna file (DNA sequence; required for read mapping with BWA or Bowtie2)?", 
+								"FNA File", JOptionPane.YES_NO_OPTION);
+
+						if (answ == JOptionPane.YES_OPTION){
+							downloadBtn.setText("Please wait...");
+							downloadBtn.setEnabled(false);
+							ftpFirstLevelCombo.setEnabled(false);
+							ftpSecondLevelCombo.setEnabled(false);
+
+							try {
+								ftp.abort();
+							} catch (IOException e1) {
+								e1.printStackTrace();
+							}
+							ftp = new FTPClient();
+							try {
+								ftp.connect("ftp.ncbi.nih.gov");
+								ftp.enterLocalPassiveMode();
+								ftp.login("anonymous", "");
+								String ftpDir = "/genomes/archive/old_genbank/Bacteria/" + ftpFirstLevelCombo.getSelectedItem() + "/";
+								FTPFile[] files = ftp.listFiles(ftpDir);
+
+								for (FTPFile t : files){
+									String fileName = (String)ftpSecondLevelCombo.getSelectedItem();
+									fileName = fileName.substring(0, fileName.indexOf(":"));
+
+									if(t.getName().contains(fileName)){
+										if(t.getName().endsWith("fna")){
+											File pttTemp = new File(projectInfo.getPath() + t.getName());
+											FileOutputStream fos = new FileOutputStream(pttTemp);
+											ftp.retrieveFile(ftpDir + t.getName(), fos);
+											pttFileTxt.setText(pttTemp.getAbsolutePath());
+										}
+									}
+								}
+
+								downloadBtn.setText("Download");
+								downloadBtn.setEnabled(true);
+								ftpFirstLevelCombo.setEnabled(true);
+								ftpSecondLevelCombo.setEnabled(true);
+							} catch (IOException e) {
+								logger.error(e.getMessage());
+								return;
+							}
+
+						}else{
+
+						}
+					}
+				})).start();
+
+			}
+		});
+
+		downloadBtn.setBounds(716, 144, 97, 25);
+		panelMain.add(downloadBtn);
+
+		JLabel lblPttFile = new JLabel("PTT File:");
+		lblPttFile.setBounds(12, 235, 79, 16);
+		panelMain.add(lblPttFile);
+
+		JLabel lblRntFile = new JLabel("RNT File:");
+		lblRntFile.setBounds(12, 267, 79, 16);
+		panelMain.add(lblRntFile);
+
+		pttFileTxt = new JTextField();
+		pttFileTxt.setBounds(85, 232, 622, 22);
+		panelMain.add(pttFileTxt);
+		pttFileTxt.setColumns(10);
+
+		rntFileTxt = new JTextField();
+		rntFileTxt.setColumns(10);
+		rntFileTxt.setBounds(85, 264, 622, 22);
+		panelMain.add(rntFileTxt);
+		pttBrowseBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath().toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+				fileChooser.setFileFilter(new FileNameExtensionFilter("PTT Files (.ptt)", "ptt"));
+				int result = fileChooser.showOpenDialog(MainFrame.this);
+
+				if(result == JFileChooser.APPROVE_OPTION){
+					pttFileTxt.setText(fileChooser.getSelectedFile().getAbsolutePath());
+				}else{
+					return;
+				}
+
+			}
+		});
+
+		pttBrowseBtn.setBounds(716, 231, 97, 25);
+		panelMain.add(pttBrowseBtn);
+		rntBrowseBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath()
+						.toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+				fileChooser.setFileFilter(new FileNameExtensionFilter("RNT Files (.rnt)", "rnt"));
+				int result = fileChooser.showOpenDialog(MainFrame.this);
+
+				if(result == JFileChooser.APPROVE_OPTION){
+					rntFileTxt.setText(fileChooser.getSelectedFile().getAbsolutePath());
+				}else{
+					return;
+				}
+			}
+		});
+
+		rntBrowseBtn.setBounds(716, 263, 97, 25);
+		panelMain.add(rntBrowseBtn);
+
+		JLabel lblOr = new JLabel("Or");
+		lblOr.setFont(new Font("Tahoma", Font.BOLD, 16));
+		lblOr.setBounds(12, 168, 51, 35);
+		panelMain.add(lblOr);
+		btnPrepareGeneFile.setToolTipText("Process files and create the .gene file");
+		btnPrepareGeneFile.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {				
+
+				prepareGeneFile();
+			}
+		});
+
+		btnPrepareGeneFile.setFont(new Font("Tahoma", Font.BOLD, 13));
+		btnPrepareGeneFile.setBounds(339, 450, 182, 25);
+		panelMain.add(btnPrepareGeneFile);
+
+		JSeparator separator_3 = new JSeparator();
+		separator_3.setBounds(52, 187, 771, 2);
+		panelMain.add(separator_3);
+
+		buttonGroup.add(databaseRadioBtn);
+		databaseRadioBtn.setToolTipText("Automatically download from the NCBI FTP Server");
+		databaseRadioBtn.setFont(new Font("Tahoma", Font.PLAIN, 16));
+		databaseRadioBtn.setBounds(10, 76, 404, 25);
+		panelMain.add(databaseRadioBtn);	
+
+		databaseRadioBtn.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				ftpFirstLevelCombo.setEnabled(true);
+				ftpSecondLevelCombo.setEnabled(true);
+				downloadBtn.setEnabled(true);
+
+				pttBrowseBtn.setEnabled(false);
+				pttFileTxt.setEnabled(false);
+				rntBrowseBtn.setEnabled(false);
+				rntFileTxt.setEnabled(false);
+
+				ftpFirstLevelCombo.removeAllItems();
+				ftpFirstLevelCombo.addItem("Retrieving genome information, Please Wait...");
+				ftpSecondLevelCombo.setEnabled(false);
+				downloadBtn.setEnabled(false);
+
+				pttFileTxt.setText("");
+				rntFileTxt.setText("");
+
+				imgFileTxt.setEnabled(false);
+				imgBrowseBtn.setEnabled(false);
+				scaffoldCombo.setEnabled(false);
+
+				(new Thread(new Runnable(){
+					@Override
+					public void run() {
+						FTPClient ftp = new FTPClient();
+						try {
+							ftp.connect("ftp.ncbi.nih.gov");
+							ftp.enterLocalPassiveMode();
+							ftp.login("anonymous", "");
+							FTPFile[] files = ftp.listFiles("/genomes/archive/old_genbank/Bacteria/");
+
+							ftpFirstLevelCombo.removeAllItems();
+							for(FTPFile t : files){
+								if(!t.getName().contains(".")){
+									ftpFirstLevelCombo.addItem(t.getName());
+								}
+								ftpSecondLevelCombo.addItem("Please Choose Your bacteria First");
+							}
+
+						} catch (IOException e) {
+							logger.error(e.getMessage());
+							return;
+						}						
+					}
+				})).start();
+
+			}
+		});
+
+		ftpFirstLevelCombo.addItemListener(new ItemListener(){
+			@SuppressWarnings("deprecation")
+			@Override
+			public void itemStateChanged(ItemEvent e) {
+
+				if(e.getStateChange() == ItemEvent.SELECTED){
+					ftpSecondLevelCombo.removeAllItems();
+					ftpSecondLevelCombo.addItem("Retieving Files List, Please Wait");
+
+					if (second_thread != null){
+						second_thread.run();
+						second_thread.stop();
+						second_thread = null;
+					}
+
+					second_thread = new Thread(new Runnable(){
+						private FTPClient ftp = null;
+						@Override
+						public void run() {
+							if (ftp != null){
+								try {
+									ftp.disconnect();
+								} catch (IOException e) {
+									e.printStackTrace();
+								}
+								return;
+							}
+
+							ftp = new FTPClient();
+
+							try {
+								ftp.connect("ftp.ncbi.nih.gov");
+								ftp.enterLocalPassiveMode();
+								ftp.login("anonymous", "");
+								String ftpDir = "/genomes/archive/old_genbank/Bacteria/" + ftpFirstLevelCombo.getSelectedItem() + "/";
+								FTPFile[] files = ftp.listFiles(ftpDir);
+								ftp.disconnect();
+
+								ftpSecondLevelCombo.removeAllItems();
+								for(FTPFile t : files){
+									if(t.getName().endsWith(".ptt")){
+										String fileName = "";
+										String bacteriaName = "";
+										String lengthString = "";
+										String line = "";
+
+										fileName = t.getName().substring(0, t.getName().length() - 4);
+
+										ftp.connect("ftp.ncbi.nih.gov");
+										ftp.enterLocalPassiveMode();
+										ftp.login("anonymous", "");
+										InputStream stream = ftp.retrieveFileStream(ftpDir + fileName + ".ptt");
+										BufferedReader ftpBr = new BufferedReader(new InputStreamReader(stream));
+
+										line = ftpBr.readLine();
+										bacteriaName = line.substring(0, line.indexOf(" -"));
+										lengthString = line.substring(line.indexOf("..") + 2);
+
+										String itemString = String.format("%s: %s (%s bp)", fileName, bacteriaName, lengthString);
+										ftpSecondLevelCombo.addItem(itemString);
+
+										ftp.disconnect();
+									}
+								}
+
+								//ftp.abort();
+
+								ftpSecondLevelCombo.setEnabled(true);
+							} catch (Exception e1) {
+								logger.error(e1.getMessage());
+								return;
+							}							
+						}
+					});	
+
+					second_thread.start();
+				}
+			}
+		});
+
+		ftpSecondLevelCombo.addItemListener(new ItemListener() {
+			@Override
+			public void itemStateChanged(ItemEvent e) {
+				if(e.getStateChange() == ItemEvent.SELECTED){
+					downloadBtn.setEnabled(true);
+				}	
+			}
+		});
+
+		buttonGroup.add(ownRadioBtn);
+		ownRadioBtn.setToolTipText("Use existing files from NCBI FTP server");
+		ownRadioBtn.setFont(new Font("Tahoma", Font.PLAIN, 16));
+		ownRadioBtn.setBounds(12, 201, 402, 25);
+		panelMain.add(ownRadioBtn);
+		ownRadioBtn.setSelected(true);
+
+		ftpFirstLevelCombo.setEnabled(false);
+		ftpSecondLevelCombo.setEditable(false);
+		downloadBtn.setEnabled(false);
+
+		ownRadioBtn.addActionListener(new ActionListener() {
+
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				ftpFirstLevelCombo.setEnabled(false);
+				ftpSecondLevelCombo.setEnabled(false);
+				downloadBtn.setEnabled(false);
+
+				pttBrowseBtn.setEnabled(true);
+				pttFileTxt.setEnabled(true);
+				rntBrowseBtn.setEnabled(true);
+				rntFileTxt.setEnabled(true);
+
+				ftpFirstLevelCombo.setEnabled(false);
+				ftpSecondLevelCombo.setEnabled(false);
+				downloadBtn.setEnabled(false);
+
+				ftpFirstLevelCombo.removeAllItems();
+				ftpSecondLevelCombo.removeAllItems();
+
+				imgFileTxt.setEnabled(false);
+				imgBrowseBtn.setEnabled(false);
+				scaffoldCombo.setEnabled(false);
+			}
+		});
+
+		rntFileTxt.setEnabled(false);
+		pttFileTxt.setEnabled(false);
+
+		JLabel lblGenesFileName = new JLabel("Gene annotation:");
+		lblGenesFileName.setFont(new Font("Tahoma", Font.PLAIN, 16));
+		lblGenesFileName.setBounds(377, 592, 163, 22);
+		panelMain.add(lblGenesFileName);
+
+		geneFileNameLbl.setFont(new Font("Tahoma", Font.PLAIN, 15));
+		geneFileNameLbl.setBounds(521, 587, 186, 33);
+		panelMain.add(geneFileNameLbl);
+
+		JLabel label = new JLabel("Or");
+		label.setFont(new Font("Tahoma", Font.BOLD, 16));
+		label.setBounds(12, 294, 51, 35);
+		panelMain.add(label);
+
+		JSeparator separator_4 = new JSeparator();
+		separator_4.setBounds(52, 313, 771, 2);
+		panelMain.add(separator_4);
+
+		buttonGroup.add(imgRadioBtn);
+		imgRadioBtn.setToolTipText("use existing files from IMG server");
+		imgRadioBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				ftpFirstLevelCombo.setEnabled(false);
+				ftpSecondLevelCombo.setEnabled(false);
+				downloadBtn.setEnabled(false);
+
+				pttBrowseBtn.setEnabled(false);
+				pttFileTxt.setEnabled(false);
+				rntBrowseBtn.setEnabled(false);
+				rntFileTxt.setEnabled(false);
+
+				ftpFirstLevelCombo.setEnabled(false);
+				ftpSecondLevelCombo.setEnabled(false);
+				downloadBtn.setEnabled(false);
+
+				ftpFirstLevelCombo.removeAllItems();
+				ftpSecondLevelCombo.removeAllItems();
+
+				imgFileTxt.setEnabled(true);
+				imgBrowseBtn.setEnabled(true);
+				scaffoldCombo.setEnabled(false);
+			}
+		});
+		imgRadioBtn.setFont(new Font("Tahoma", Font.PLAIN, 16));
+		imgRadioBtn.setBounds(12, 322, 402, 25);
+		panelMain.add(imgRadioBtn);
+
+		JLabel lblImgFile = new JLabel("IMG file:");
+		lblImgFile.setBounds(12, 382, 79, 16);
+		panelMain.add(lblImgFile);
+
+		imgFileTxt = new JTextField();
+		imgFileTxt.setToolTipText("Path to the IMG file, use the browse button");
+		imgFileTxt.setEditable(false);
+		imgFileTxt.setEnabled(false);
+		imgFileTxt.setColumns(10);
+		imgFileTxt.setBounds(148, 379, 559, 22);
+		panelMain.add(imgFileTxt);
+		imgBrowseBtn.setToolTipText("Select the file downloaded from IMG server");
+		imgBrowseBtn.setEnabled(false);
+		imgBrowseBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath().toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+				fileChooser.setFileFilter(new FileNameExtensionFilter("XLS File (.xls)", "xls"));
+				int result = fileChooser.showOpenDialog(MainFrame.this);
+
+				if (result == JFileChooser.APPROVE_OPTION){
+					imgFileTxt.setText(fileChooser.getSelectedFile().getAbsolutePath());
+					try {
+						PrepareFiles.extractScaffolds(fileChooser.getSelectedFile().getAbsolutePath(), projectInfo, MainFrame.this.scaffoldCombo);
+					} catch (IOException e1) {
+						logger.error(e1.getMessage());
+						return;
+					}
+				}
+			}
+		});
+
+		imgBrowseBtn.setBounds(716, 378, 97, 25);
+		panelMain.add(imgBrowseBtn);
+
+		JLabel lblSelectYourScaffold = new JLabel("Select a scaffold:");
+		lblSelectYourScaffold.setBounds(12, 412, 112, 16);
+		panelMain.add(lblSelectYourScaffold);
+		scaffoldCombo.setToolTipText("Select the scaffold within the IMG file");
+		scaffoldCombo.setEnabled(false);
+
+		scaffoldCombo.setBounds(148, 410, 559, 20);
+		panelMain.add(scaffoldCombo);
+
+		JSeparator separator_7 = new JSeparator();
+		separator_7.setBounds(0, 493, 823, 2);
+		panelMain.add(separator_7);
+
+		JLabel lblyouCanDownload = new JLabel("You can download the IMG file by clicking on this link");
+		lblyouCanDownload.setBounds(12, 354, 695, 16);
+		panelMain.add(lblyouCanDownload);
+		infoLbl.setForeground(Color.RED);
+
+		infoLbl.setFont(new Font("Tahoma", Font.ITALIC, 11));
+		infoLbl.setBounds(12, 6, 665, 14);
+		panelMain.add(infoLbl);
+
+		JLabel lblNeedHelp = new JLabel("(?)");
+		lblNeedHelp.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				JOptionPane.showMessageDialog(MainFrame.this, "This will guide you to finding the protein-coding (.ptt file) and RNA (.rnt file) gene\n"
+						+ "annotation at the FTP server of the National Center for Biotechnology Information\n"
+						+ "(ftp://ftp.ncbi.nih.gov/genomes/archive/old_genbank/Bacteria/)");
+			}
+		});
+		lblNeedHelp.setToolTipText("Click me!");
+		lblNeedHelp.setForeground(Color.BLUE);
+		lblNeedHelp.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		lblNeedHelp.setBounds(433, 85, 88, 14);
+		panelMain.add(lblNeedHelp);
+
+		JLabel lblhelp = new JLabel("(?)");
+		lblhelp.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(MainFrame.this, "If you previously downloaded the .ppt and .rnt files from NCBI you can select them here.\n"
+						+ "You can also manually edit the .ptt and .rnt files before creating a new project as long as you\n"
+						+ "follow the appropriate format of the file.");
+			}
+		});
+		lblhelp.setToolTipText("Click me!");
+		lblhelp.setForeground(Color.BLUE);
+		lblhelp.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		lblhelp.setBounds(433, 207, 88, 14);
+		panelMain.add(lblhelp);
+
+		JLabel label_2 = new JLabel("(?)");
+		label_2.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(MainFrame.this, "Alternatively, you can use annotation downloaded from Integrated Microbial Genomes (http://img.jgi.doe.gov/).\n"
+						+ "To download the IMG annotation, find the desired genome in the IMG database (finished genomes only),\n"
+						+ "select 'Export gene information' (near the bottom of the page), and save the .xls file from the follwoing page.");
+			}
+		});
+		label_2.setToolTipText( "Click me!");
+		label_2.setForeground(Color.BLUE);
+		label_2.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_2.setBounds(433, 329, 88, 14);
+		panelMain.add(label_2);
+
+		JLabel label_1 = new JLabel("(?)");
+		label_1.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(MainFrame.this, "The IMG annotation may include data for multiple scaffolds (e.g., chromosomes or plasmids)\n"
+						+ "Select the one you wish to use.");
+			}
+		});
+		label_1.setToolTipText("Click me!");
+		label_1.setForeground(Color.BLUE);
+		label_1.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_1.setBounds(120, 412, 88, 14);
+		panelMain.add(label_1);
+
+		JLabel lblSequqenceLength = new JLabel("Sequqence length (bp):");
+		lblSequqenceLength.setFont(new Font("Tahoma", Font.PLAIN, 16));
+		lblSequqenceLength.setBounds(378, 555, 204, 22);
+		panelMain.add(lblSequqenceLength);
+
+		sequenceLengthLbl.setFont(new Font("Tahoma", Font.PLAIN, 15));
+		sequenceLengthLbl.setBounds(575, 550, 178, 33);
+		panelMain.add(sequenceLengthLbl);
+
+		lblPleaseEnterAn.setForeground(Color.RED);
+		lblPleaseEnterAn.setBounds(498, 37, 293, 14);
+		lblPleaseEnterAn.setVisible(false);
+		panelMain.add(lblPleaseEnterAn);
+
+		JPanel panelInitialize = new JPanel();
+		tabbedPane.addTab("Manage Libraries", null, panelInitialize, null);
+		panelInitialize.setLayout(null);
+
+		JLabel lblBrowseFoThe = new JLabel("Add new library to the project:");
+		lblBrowseFoThe.setBounds(12, 149, 799, 16);
+		panelInitialize.add(lblBrowseFoThe);
+
+		samFilePathTxt = new JTextField();
+		samFilePathTxt.setToolTipText("Path to the SAM file");
+		samFilePathTxt.setBounds(12, 178, 581, 22);
+		panelInitialize.add(samFilePathTxt);
+		samFilePathTxt.setColumns(10);
+		browseForSamBtn.setToolTipText("Use this to browse for the SAM file");
+
+		browseForSamBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath().toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+				fileChooser.setFileFilter(new FileNameExtensionFilter("SAM Files (.sam) | Insertion Positions (.INSPO)", "sam", "inspo"));
+				int result = fileChooser.showOpenDialog(MainFrame.this);
+
+				if (result == JFileChooser.APPROVE_OPTION){
+					MainFrame.this.samFilePathTxt.setText(fileChooser.getSelectedFile().getAbsolutePath());
+					MainFrame.this.extractInsBtn.setEnabled(true);
+					MainFrame.this.samFilePathTxt.setEnabled(false);
+					MainFrame.this.browseForSamBtn.setEnabled(false);
+
+					if(fileChooser.getSelectedFile().getName().contains(".inspo")){
+						doneLbl1.setVisible(true);
+						loadingLbl.setBounds(22, 239, 30, 16);
+						extractInsLbl.setForeground(Color.BLACK);
+					}
+				}
+			}
+		});
+		browseForSamBtn.setBounds(603, 176, 99, 25);
+		panelInitialize.add(browseForSamBtn);
+
+		extractInsLbl.setForeground(Color.LIGHT_GRAY);
+		extractInsLbl.setBounds(54, 219, 411, 16);
+		panelInitialize.add(extractInsLbl);
+		extractInsBtn.setToolTipText("Process and extract the SAM file");
+		extractInsBtn.setEnabled(false);
+		extractInsBtn.addActionListener(new ActionListener() {
+			@SuppressWarnings("resource")
+			public void actionPerformed(ActionEvent arg0) {
+				MainFrame.this.extractInsLbl.setForeground(Color.BLACK);
+				MainFrame.this.extractInsBtn.setEnabled(false);
+				MainFrame.this.extractInsBtn.setText("Wait");
+
+				if (samFilePathTxt.getText() == null || samFilePathTxt.getText().equals("")){
+					JOptionPane.showMessageDialog(MainFrame.this, "Select an input file and try again.");
+					setToDefaultState();
+					return;
+				}
+
+				Integer uniqueInsertionsLimit = 0;
+				try{
+					uniqueInsertionsLimit = Integer.parseInt(removeUniqueInsertionsTxt.getText());
+				}catch(NumberFormatException e){
+					JOptionPane.showMessageDialog(MainFrame.this, "Please enter a valid number for fileds highlighted with red.");
+					clearTheForm();
+					return;
+				}
+				if(samFilePathTxt.getText().endsWith(".inspo")){
+					String newPath = projectInfo.getPath() + PrepareFiles.prepareFileName(samFilePathTxt.getText(), ".inspo");
+
+					File oldFile = new File(samFilePathTxt.getText());
+					File newFile = new File(newPath);
+
+					if (newFile.exists()){
+						newPath = projectInfo.getPath() + PrepareFiles.prepareFileName(samFilePathTxt.getText(), "-temp.inspo");
+						newFile = new File(newPath);
+					}
+
+					FileChannel destination;
+					FileChannel source;
+					try {
+						destination = new FileOutputStream(newFile).getChannel();
+						source = new FileInputStream(oldFile).getChannel();
+
+						if(destination != null && source != null){
+							destination.transferFrom(source, 0, source.size());
+						}
+
+						if(source != null){
+							source.close();
+						}
+
+						if(destination != null){
+							destination.close();
+						}
+					} catch (IOException e) {
+						e.printStackTrace();
+					}
+					loadingLbl.setBounds(22, 239, 30, 16);
+					loadingLbl.setVisible(true);
+					samFilePathTxt.setText(newPath.replace("-temp", ""));
+					SortInsertions run = new SortInsertions(uniqueInsertionsLimit);
+					Thread runThread = new Thread(run);
+					runThread.start();
+				}else{
+					loadingLbl.setBounds(22, 219, 30, 16);
+					loadingLbl.setVisible(true);
+					ExtractInsertions run = new ExtractInsertions(uniqueInsertionsLimit);
+					Thread runThread = new Thread(run);
+					runThread.start();
+				}
+			}
+		});
+
+		extractInsBtn.setBounds(712, 177, 99, 25);
+		panelInitialize.add(extractInsBtn);
+
+		sortInsLbl.setForeground(Color.LIGHT_GRAY);
+		sortInsLbl.setBounds(54, 238, 411, 16);
+		panelInitialize.add(sortInsLbl);
+
+		countUniLbl.setForeground(Color.LIGHT_GRAY);
+		countUniLbl.setBounds(54, 257, 411, 16);
+		panelInitialize.add(countUniLbl);
+
+		sortUniLbl.setForeground(Color.LIGHT_GRAY);
+		sortUniLbl.setBounds(54, 276, 411, 16);
+		panelInitialize.add(sortUniLbl);
+		cancelLibSaveBtn.setToolTipText("Clear everything and start over");
+		cancelLibSaveBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+
+				clearTheForm();
+
+			}
+		});
+
+		cancelLibSaveBtn.setBounds(658, 286, 153, 25);
+		panelInitialize.add(cancelLibSaveBtn);
+
+		JSeparator separator_2 = new JSeparator();
+		separator_2.setBounds(0, 322, 821, 2);
+		panelInitialize.add(separator_2);
+
+		JLabel lblRemoveExistingLibraries = new JLabel("Edit existing libraries:");
+		lblRemoveExistingLibraries.setBounds(10, 337, 313, 16);
+		panelInitialize.add(lblRemoveExistingLibraries);
+		libraryComboBox.setToolTipText("Select a library to edit");
+
+		libraryComboBox.setBounds(12, 366, 581, 22);
+		panelInitialize.add(libraryComboBox);
+		removeLibBtn.setToolTipText("Remove the selected library");
+
+		removeLibBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				String selectedLib = (String) libraryComboBox.getSelectedItem();
+
+				BufferedReader br = null;
+				BufferedWriter bw = null;
+				File tempCopy = null;
+				try {
+					tempCopy = new File(projectInfo.getPath() + "temp.pro");
+					br = new BufferedReader(new FileReader(
+							projectInfo.getFile()));
+					bw = new BufferedWriter(new FileWriter(
+							tempCopy));
+
+					String line = br.readLine();
+					bw.write(line + "\n");
+
+					line = br.readLine();
+					bw.write(line + "\n");
+
+					line = br.readLine();
+					bw.write(line + "\n");
+
+					line = br.readLine();
+					while(line != null){
+						if (selectedLib.compareTo(line.substring(0, line.length() - 6)) == 0){					
+							File temp = new File(projectInfo.getPath() + selectedLib + ".inspo");
+							temp.delete();
+
+							temp = new File(projectInfo.getPath() + selectedLib + ".inspos");
+							temp.delete();
+
+							temp = new File(projectInfo.getPath() + selectedLib + ".inspou");
+							temp.delete();
+
+							temp = new File(projectInfo.getPath() + selectedLib + ".inspous");
+							temp.delete();
+
+							temp = new File(projectInfo.getPath() + selectedLib + ".data");
+							temp.delete();
+
+							br.readLine();
+							br.readLine();
+							br.readLine();
+							line = br.readLine();
+
+						}else{
+							bw.write(line + "\n");
+
+							line = br.readLine();
+							bw.write(line + "\n");
+
+							line = br.readLine();
+							bw.write(line + "\n");
+
+							line = br.readLine();
+							bw.write(line + "\n");
+
+							line = br.readLine();
+						}
+
+					}
+
+				} catch (IOException e) {
+					logger.error(e.getMessage());
+					return;
+				} finally {
+					try {
+						br.close();
+						bw.close();
+					} catch (IOException e) {
+						logger.error(e.getMessage());
+						return;
+					}
+				}
+
+				File pro = projectInfo.getFile();
+				pro.delete();
+				tempCopy.renameTo(pro);
+				initiateLibraryComboBox();
+				libraryCountLbl.setText((Integer.parseInt(libraryCountLbl.getText()) - 1) + "");
+			}
+		});
+		removeLibBtn.setBounds(714, 365, 97, 25);
+		panelInitialize.add(removeLibBtn);
+		renameLibBtn.setToolTipText("Rename the selected library");
+
+		renameLibBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				String newName = JOptionPane.showInputDialog(MainFrame.this, "Enter the New Name");
+				String selectedLib = (String) libraryComboBox.getSelectedItem();
+
+				renameLibrary(newName, selectedLib);
+			}
+		});
+		renameLibBtn.setBounds(605, 365, 97, 25);
+		panelInitialize.add(renameLibBtn);
+
+		loadingLbl.setIcon(new ImageIcon(MainFrame.class.getResource("/resources/load.gif")));
+		loadingLbl.setBounds(14, 219, 30, 16);
+		panelInitialize.add(loadingLbl);
+
+		doneLbl1.setIcon(new ImageIcon(MainFrame.class.getResource("/resources/done.gif")));
+		doneLbl1.setBounds(22, 219, 23, 14);
+		panelInitialize.add(doneLbl1);
+
+		doneLbl2.setIcon(new ImageIcon(MainFrame.class.getResource("/resources/done.gif")));
+		doneLbl2.setBounds(21, 239, 23, 14);
+		panelInitialize.add(doneLbl2);
+
+		doneLbl3.setIcon(new ImageIcon(MainFrame.class.getResource("/resources/done.gif")));
+		doneLbl3.setBounds(21, 258, 23, 14);
+		panelInitialize.add(doneLbl3);
+
+		doneLbl4.setIcon(new ImageIcon(MainFrame.class.getResource("/resources/done.gif")));
+		doneLbl4.setBounds(21, 277, 23, 14);
+		panelInitialize.add(doneLbl4);
+
+		JSeparator separator_9 = new JSeparator();
+		separator_9.setBounds(0, 136, 821, 2);
+		panelInitialize.add(separator_9);
+
+		JLabel lblChooseALibrary = new JLabel("Choose a library:");
+		lblChooseALibrary.setBounds(12, 458, 286, 14);
+		panelInitialize.add(lblChooseALibrary);
+		plotLibraryCombo.addItemListener(new ItemListener() {
+			public void itemStateChanged(ItemEvent arg0) {
+				reloadWinInfo();
+			}
+		});
+		plotLibraryCombo.setToolTipText("Select a libray to plot");
+
+		plotLibraryCombo.setBounds(12, 483, 402, 20);
+		panelInitialize.add(plotLibraryCombo);
+		plotBtn.setToolTipText("Plot the selected library");
+
+		plotBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				plotDataMethod();
+			}
+		});
+		plotBtn.setBounds(691, 516, 87, 23);
+		panelInitialize.add(plotBtn);
+
+		winLenTxt = new JTextField();
+		winLenTxt.addFocusListener(new FocusAdapter() {
+			@Override
+			public void focusGained(FocusEvent arg0) {
+				highlightAllTheText((JTextField) arg0.getComponent());
+			}
+		});
+		winLenTxt.setToolTipText("Enter the window length");
+		winLenTxt.setColumns(10);
+		winLenTxt.setBounds(424, 483, 56, 20);
+		winLenTxt.setInputVerifier(new IntegerInputVerifier(errorMsgLbl));
+		panelInitialize.add(winLenTxt);
+
+		winStepTxt = new JTextField();
+		winStepTxt.addFocusListener(new FocusAdapter() {
+			@Override
+			public void focusGained(FocusEvent arg0) {
+				highlightAllTheText((JTextField) arg0.getComponent());
+			}
+		});
+		winStepTxt.setToolTipText("Enter window step size");
+		winStepTxt.setColumns(10);
+		winStepTxt.setBounds(490, 483, 65, 20);
+		winStepTxt.setInputVerifier(new IntegerInputVerifier(errorMsgLbl));
+		panelInitialize.add(winStepTxt);
+
+		lblWindowLength.setBounds(392, 468, 123, 14);
+		panelInitialize.add(lblWindowLength);
+
+		JLabel label_5 = new JLabel("Step:");
+		label_5.setBounds(490, 468, 108, 14);
+		panelInitialize.add(label_5);
+
+		JSeparator separator_10 = new JSeparator();
+		separator_10.setBounds(0, 420, 821, 2);
+		panelInitialize.add(separator_10);
+
+		JLabel lblPlotTheDistribution = new JLabel("Plot the distribution of the number of unique insertions or all sequence reads per window for a selected library.");
+		lblPlotTheDistribution.setBounds(10, 433, 801, 14);
+		panelInitialize.add(lblPlotTheDistribution);
+
+		plotWaitLbl.setIcon(new ImageIcon(MainFrame.class.getResource("/resources/load.gif")));
+		plotWaitLbl.setBounds(12, 606, 183, 14);
+		panelInitialize.add(plotWaitLbl);
+
+		JLabel label_3 = new JLabel("(?)");
+		label_3.setToolTipText("Click me!");
+		label_3.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(MainFrame.this, 
+						"This is the same plot as shown in Figure 1 of Sarmiento et al., PNAS 110:4726-4731, 2013. A strong peak at zero separated from a wider peak for larger\n"
+								+ "numbers of insertions indicates that the window size is suitable for detecting essential genes in the given library. Larger window sizes provide better\n"
+								+ "distinction between essential and non-essential genes but they can miss essential genes shorter than the window length." );
+			}
+		});
+		label_3.setForeground(Color.BLUE);
+		label_3.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_3.setBounds(781, 520, 30, 14);
+		panelInitialize.add(label_3);
+
+		maxNumInsTxt = new JTextField();
+		maxNumInsTxt.addFocusListener(new FocusAdapter() {
+			@Override
+			public void focusGained(FocusEvent arg0) {
+				highlightAllTheText((JTextField) arg0.getComponent());
+			}
+		});
+		maxNumInsTxt.setToolTipText("Enter the window length");
+		maxNumInsTxt.setText("3");
+		maxNumInsTxt.setColumns(10);
+		maxNumInsTxt.setBounds(426, 551, 118, 20);
+		maxNumInsTxt.setInputVerifier(new IntegerInputVerifier(errorMsgLbl));
+		panelInitialize.add(maxNumInsTxt);
+
+		JLabel lblMaxNumberOf = new JLabel("Max number of insertions/reads:");
+		lblMaxNumberOf.setBounds(233, 554, 183, 14);
+		panelInitialize.add(lblMaxNumberOf);
+		maxNumInsBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				maxNumInsrtions();
+			}
+		});
+
+		maxNumInsBtn.setBounds(563, 550, 215, 23);
+		panelInitialize.add(maxNumInsBtn);
+		countOnlyUniqueRadio.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				maxNumInsTxt.setText("3");
+			}
+		});
+		countOnlyUniqueRadio.setSelected(true);
+
+		countOnlyUniqueRadio.setBounds(12, 516, 249, 23);
+		panelInitialize.add(countOnlyUniqueRadio);
+		countAllReadsRadio.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				maxNumInsTxt.setText("10");
+			}
+		});
+
+		countAllReadsRadio.setBounds(12, 542, 215, 23);
+		panelInitialize.add(countAllReadsRadio);
+		numberOfReads.add(countOnlyUniqueRadio);
+		numberOfReads.add(countAllReadsRadio);
+
+		JLabel label_7 = new JLabel("(?)");
+		label_7.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(MainFrame.this, "This will identify chromosomal segments with low transposon insertion density,\n"
+						+ "possibly indicating that these segments may be essential. Specifically, it will list\n"
+						+ "starts and ends of the regions comprised of overlapping windows with no more\n"
+						+ "than the specified number of insertions or reads.");
+			}
+		});
+		label_7.setToolTipText("Click me!");
+		label_7.setForeground(Color.BLUE);
+		label_7.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_7.setBounds(781, 554, 30, 14);
+		panelInitialize.add(label_7);
+
+		JXLabel samDescLbl = new JXLabel("New label");
+		samDescLbl.setFont(new Font("Tahoma", Font.PLAIN, 13));
+		samDescLbl.setText("You can add and manage transposon insertion mutant libraries here. You need the .sam file from the Burrows-Wheeler aligner, Bowtie2, or "
+				+ "similar software. (bwa, bio-bwa.sourceforge.net; bowtie2, bowtie-bio.sourceforge.net/bowtie2) to add a library to your project. "
+				+ "SAM stands for Sequence Alignment/Map format. It is a TAB-delimited text format file that contains the alignment of the sequence reads to the genome. If "
+				+ "the Burrows-Wheeler Aligner is installed on this computer you may be able to run it from this application. To add new library, provide the name for the library"
+				+ ", navigate to the .sam file using the 'Browse' button, and then click 'Extract'.");
+		samDescLbl.setBounds(12, 11, 799, 94);
+		panelInitialize.add(samDescLbl);
+		samDescLbl.setLineWrap(true);
+
+		JLabel label_8 = new JLabel("(?)");
+		label_8.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				JOptionPane.showMessageDialog(MainFrame.this, "This will process the SAM file to extract number number of sequence reads\n"
+						+ "corresponding to every possible transposon location in the genome." );
+			}
+		});
+		label_8.setToolTipText("Click me!");
+		label_8.setForeground(Color.BLUE);
+		label_8.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_8.setBounds(12, 111, 30, 14);
+		panelInitialize.add(label_8);
+
+		btnOptimal.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				findOptimalWinLength();
+			}
+		});
+		btnOptimal.setBounds(565, 482, 210, 23);
+		panelInitialize.add(btnOptimal);
+
+		JLabel label_9 = new JLabel("(?)");
+		label_9.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				JOptionPane.showMessageDialog(MainFrame.this, "The program will attempt to find the optimal window size by analyzing the distribution of insertions\n"
+						+ "among the sequence windows. Depending on the character of the data, this procedure may not always\n"
+						+ "work and you should verify that the function should be bimodal, separating windows overlapping with\n"
+						+ "essential and nonessential genes. You can manually change the window size and explore the distribution\n"
+						+ "for different window sizes using the 'Plot' button below. This feature is intended to be used only with\n"
+						+ "unique insertions.");
+			}
+		});
+		label_9.setToolTipText("Click me!");
+		label_9.setForeground(Color.BLUE);
+		label_9.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_9.setBounds(781, 486, 30, 14);
+		panelInitialize.add(label_9);
+		winlenLbl.setIcon(new ImageIcon(MainFrame.class.getResource("/resources/load.gif")));
+		winlenLbl.setVisible(false);
+
+		winlenLbl.setBounds(563, 486, 215, 14);
+		panelInitialize.add(winlenLbl);
+
+		errorMsgLbl.setForeground(Color.RED);
+		errorMsgLbl.setBounds(279, 606, 455, 14);
+		errorMsgLbl.setVisible(false);
+		panelInitialize.add(errorMsgLbl);
+
+		lblRemoveUniqueInsertions.setBounds(475, 214, 336, 14);
+		panelInitialize.add(lblRemoveUniqueInsertions);
+
+		removeUniqueInsertionsTxt = new JTextField();
+		removeUniqueInsertionsTxt.setText("0");
+		removeUniqueInsertionsTxt.setBounds(710, 211, 38, 20);
+		panelInitialize.add(removeUniqueInsertionsTxt);
+		removeUniqueInsertionsTxt.setColumns(10);
+		removeUniqueInsertionsTxt.setInputVerifier(new IntegerInputVerifier(errorMsgLbl));
+
+		lblReads.setBounds(760, 215, 46, 14);
+		panelInitialize.add(lblReads);
+
+		label_10.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				JOptionPane.showMessageDialog(MainFrame.this, "Some unique insertions may be represented by a single read (or only a\n"
+						+ "few reads). These could result from sequence reads that were incorrectly\n"
+						+ "mapped to the genome, or from other artifacts. You can use this\n"
+						+ "parameter to remove such unique insertions and the associated reads\n"
+						+ "from the data.");
+			}
+		});
+		label_10.setToolTipText("Click me!");
+		label_10.setForeground(Color.BLUE);
+		label_10.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_10.setBounds(797, 215, 30, 14);
+		panelInitialize.add(label_10);
+
+		btnAnotherPlot.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				anotherPlot();
+			}
+		});
+		btnAnotherPlot.setBounds(551, 584, 227, 23);
+		panelInitialize.add(btnAnotherPlot);
+
+		JLabel label_11 = new JLabel("(?)");
+		label_11.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				JOptionPane.showMessageDialog(MainFrame.this, "Assuming that unique insertions represent different mutants, if each mutant had\n"
+						+ "an equal chance to be represented by a sequence read in the sequencing experiment,\n"
+						+ "the number of reads per unique insertion would follow approximately a normal\n"
+						+ "distribution. However, this is rarely the case with real data. This option allows you\n"
+						+ "to investigate how the distribution of reads differs from the random expectation.");
+			}
+		});
+		label_11.setToolTipText("Click me!");
+		label_11.setForeground(Color.BLUE);
+		label_11.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_11.setBounds(781, 590, 30, 14);
+		panelInitialize.add(label_11);
+		loadingLbl.setVisible(false);
+		doneLbl1.setVisible(false);
+		doneLbl2.setVisible(false);
+		doneLbl3.setVisible(false);
+		doneLbl4.setVisible(false);
+
+		JPanel panel = new JPanel();
+		tabbedPane.addTab("Manage Data Tables", null, panel, null);
+		panel.setLayout(null);
+
+		JLabel lblAddNewData = new JLabel("Create new data table:");
+		lblAddNewData.setBounds(10, 55, 290, 16);
+		panel.add(lblAddNewData);
+		addNewDataTableBtn.setToolTipText("Add new data table to the project, after clicking just enter the name of the table.");
+
+		addNewDataTableBtn.addActionListener(new ActionListener() {
+			@SuppressWarnings("resource")
+			public void actionPerformed(ActionEvent arg0) {
+
+				String name = JOptionPane.showInputDialog(MainFrame.this, "Enter New Table Name:");
+
+				if(name == null || name.compareTo("") == 0){
+					JOptionPane.showMessageDialog(MainFrame.this, "Please enter table name!");
+					return;
+				}
+
+				File newTable = new File(projectInfo.getPath() + name + ".table.xls"); //REPLACE
+				if (newTable.exists()){
+					JOptionPane.showMessageDialog(MainFrame.this, "A table with this name already exists. Try another name.");
+					return;
+				}
+
+				if(hasGeneFile){
+
+					File tempGene = projectInfo.getGeneFile();
+
+					try {
+						FileChannel destination = new FileOutputStream(newTable).getChannel();
+						FileChannel source = new FileInputStream(tempGene).getChannel();
+
+						if(destination != null && source != null){
+							destination.transferFrom(source, 0, source.size());
+						}
+
+						if(source != null){
+							source.close();
+						}
+
+						if(destination != null){
+							destination.close();
+						}
+
+						JOptionPane.showMessageDialog(MainFrame.this, "Table was created successfully!");
+						initiateDataTablesComboBox();
+						dataTableCombo.setSelectedIndex(0);
+						dataTableCountLbl.setText((Integer.parseInt(dataTableCountLbl.getText()) + 1) + "");
+
+					} catch (IOException e) {
+						logger.error(e.getMessage());
+						return;
+					}
+				}else{
+					JOptionPane.showMessageDialog(MainFrame.this, "*.gene File does not exists. The Table can't be created.");
+				}
+
+			}
+		});
+		addNewDataTableBtn.setBounds(187, 52, 147, 23);
+		panel.add(addNewDataTableBtn);
+
+		JSeparator separator_5 = new JSeparator();
+		separator_5.setBounds(0, 86, 823, 8);
+		panel.add(separator_5);
+
+		JLabel lblOldLibraries = new JLabel("Manage existing tables:");
+		lblOldLibraries.setBounds(10, 105, 311, 16);
+		panel.add(lblOldLibraries);
+		dataTableCombo.setToolTipText("Just select the data table you want to edit");
+
+		dataTableCombo.setBounds(10, 132, 433, 20);
+		panel.add(dataTableCombo);
+		dataTableRenameBtn.setToolTipText("Rename the data table in the project");
+		dataTableRenameBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+
+				String newName = JOptionPane.showInputDialog(MainFrame.this, "Please enter the new name:");
+				if(newName == null || newName.compareTo("") == 0){
+					JOptionPane.showMessageDialog(MainFrame.this, "You must enter the new name!");
+					return;
+				}
+
+				String selectedTable = (String)dataTableCombo.getSelectedItem();
+				File oldFile = new File(projectInfo.getPath() + selectedTable + ".table.xls"); //REPLACE
+				File newFile = new File(projectInfo.getPath() + newName + ".table.xls"); //REPLACE
+
+				boolean done = oldFile.renameTo(newFile);
+
+				if(!done){
+					JOptionPane.showMessageDialog(MainFrame.this, "Rename could not take part!");
+					return;
+				}
+
+				initiateDataTablesComboBox();
+			}
+		});
+
+		dataTableRenameBtn.setBounds(675, 131, 138, 23);
+		panel.add(dataTableRenameBtn);
+		dataTableRemoveBtn.setToolTipText("Remove the selected data table from the project");
+		dataTableRemoveBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				File table = new File(projectInfo.getPath() + dataTableCombo.getSelectedItem() + ".table.xls"); //REPLACE
+
+				if(table.exists()){
+					if(!table.delete()){
+						JOptionPane.showMessageDialog(MainFrame.this, "Deletion could not take part!!!");
+					}else{
+						initiateDataTablesComboBox();
+						dataTableCountLbl.setText((Integer.parseInt(dataTableCountLbl.getText()) - 1) + "");
+					}
+				}else{
+					JOptionPane.showMessageDialog(MainFrame.this, "The selected file does not exists.");
+				}
+			}
+		});
+
+		dataTableRemoveBtn.setBounds(675, 165, 138, 23);
+		panel.add(dataTableRemoveBtn);
+		openAsSpreadsheetBtn.setToolTipText("Open the data table in a seperate editor so that you can edit it on your own.");
+		openAsSpreadsheetBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+
+				try {
+					prepareXlsFileAndOpen();
+				} catch (IOException e1) {
+					logger.error(e1.getMessage());
+					return;
+				}
+
+			}
+		});
+
+		openAsSpreadsheetBtn.setBounds(453, 132, 212, 23);
+		panel.add(openAsSpreadsheetBtn);
+		replaceXlsBtn.setToolTipText("Replace editted data table with the original one");
+
+		replaceXlsBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				replaceXlsFile();
+			}
+		});
+		replaceXlsBtn.setEnabled(false);
+		tableCancelChangeBtn.setToolTipText("Cancel editing and ignore the changes");
+		tableCancelChangeBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+
+				File xlsFile = new File(projectInfo.getPath() + dataTableCombo.getSelectedItem() + " - temp.table.xls"); //REPLACE
+				if(xlsFile.delete()){
+
+					for (int i = 0; i < tabbedPane.getTabCount(); i++){
+						tabbedPane.setEnabledAt(i, true);
+					}
+					infoLbl.setVisible(false);
+
+					addNewDataTableBtn.setEnabled(true);
+					openAsSpreadsheetBtn.setEnabled(true);
+					dataTableRemoveBtn.setEnabled(true);
+					dataTableRenameBtn.setEnabled(true);
+					dataTableCombo.setEnabled(true);
+					addNewIndicesBtn.setEnabled(true);
+					replaceXlsBtn.setEnabled(false);
+					tableCancelChangeBtn.setEnabled(false);
+
+				}else{
+					JOptionPane.showMessageDialog(MainFrame.this, "Please close the spreadsheet application.", "Could not delete the temp file", JOptionPane.ERROR_MESSAGE);
+				}
+			}
+		});
+		tableCancelChangeBtn.setEnabled(false);
+		replaceXlsBtn.setFont(new Font("Tahoma", Font.BOLD, 11));
+		replaceXlsBtn.setBounds(453, 166, 101, 23);
+		panel.add(replaceXlsBtn);
+		tableCancelChangeBtn.setEnabled(false);
+
+		tableCancelChangeBtn.setBounds(564, 166, 101, 23);
+		panel.add(tableCancelChangeBtn);
+
+		JLabel lblNewLabel_3 = new JLabel("Create and manage spreadsheets with gene information.");
+		lblNewLabel_3.setBounds(10, 11, 475, 14);
+		panel.add(lblNewLabel_3);
+
+		JLabel label_6 = new JLabel("(?)");
+		label_6.setToolTipText("Click me!");
+		label_6.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(MainFrame.this, ""
+						+ "Once you create a table you can subsequently calculate essentiality indices (EI) for all genes using different libraries and different\n"
+						+ "parameters, as well as perform other forms of data analysis. Each form of data analysis will add a new column of data to the existing\n"
+						+ "table. You can also open the spreadsheet in Excel or other external software and use its functions to analyze the data. If you use\n"
+						+ "external software make sure that you do not alter the format of the table and save the file as tab-delimited text." );
+			}
+		});
+		label_6.setForeground(Color.BLUE);
+		label_6.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_6.setBounds(453, 11, 30, 14);
+		panel.add(label_6);
+
+		JSeparator separator_6 = new JSeparator();
+		separator_6.setBounds(0, 39, 823, 8);
+		panel.add(separator_6);
+		addNewIndicesBtn.setToolTipText("You can add extra data to your data tables in this subsection");
+
+		addNewIndicesBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+
+				AddMoreIndices addFrame = new AddMoreIndices((String) dataTableCombo.getSelectedItem(), projectInfo, MainFrame.this);
+				addFrame.setVisible(true);
+
+			}
+		});
+		addNewIndicesBtn.setBounds(10, 165, 433, 23);
+		panel.add(addNewIndicesBtn);
+
+		JMenuBar menuBar = new JMenuBar();
+		setJMenuBar(menuBar);
+
+		JMenu mnMenu = new JMenu("Menu");
+		menuBar.add(mnMenu);
+
+		JMenuItem mntmOpenProject = new JMenuItem("Open Project");
+		mntmOpenProject.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				WorkspaceChooser ws = new WorkspaceChooser();
+				ws.setVisible(true);
+
+				MainFrame.this.setVisible(false);
+				MainFrame.this.dispose();
+			}
+		});
+		mnMenu.add(mntmOpenProject);
+
+		JSeparator separator_1 = new JSeparator();
+		mnMenu.add(separator_1);
+
+		JMenuItem mntmExit = new JMenuItem("Exit");
+		mntmExit.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				System.exit(0);
+			}
+		});
+		mnMenu.add(mntmExit);
+
+		JPanel panel_3 = new JPanel();
+		tabbedPane.addTab("BWA", null, panel_3, null);
+		panel_3.setLayout(null);
+
+		JLabel lblNewLabel = new JLabel("1. If you already have the 'bwa' and 'samtools' installed on your machine you can use this part.");
+		lblNewLabel.setBounds(10, 11, 697, 14);
+		panel_3.add(lblNewLabel);
+
+		JLabel lblIfYouDont = new JLabel("2. If you don't have them, you can use the Shell Scripts below to autommatically install them");
+		lblIfYouDont.setBounds(10, 37, 745, 14);
+		panel_3.add(lblIfYouDont);
+		alreadyInstalledRadio.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				bwaInstallBtn.setEnabled(false);
+
+				alreadyInstalledRadio.setSelected(true);
+			}
+		});
+
+		alreadyInstalledRadio.setSelected(true);
+		alreadyInstalledRadio.setBounds(10, 85, 191, 23);
+		panel_3.add(alreadyInstalledRadio);
+		useScriptsRadio.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				bwaInstallBtn.setEnabled(true);
+			}
+		});
+
+		useScriptsRadio.setBounds(10, 111, 292, 23);
+		panel_3.add(useScriptsRadio);
+		bwaInstallBtn.setToolTipText("Install BWA program");
+		bwaInstallBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+
+				installBWA();
+
+			}
+		});
+
+		bwaInstallBtn.setBounds(357, 111, 203, 23);
+		panel_3.add(bwaInstallBtn);
+
+		JSeparator separator_8 = new JSeparator();
+		separator_8.setBounds(0, 165, 823, 2);
+		panel_3.add(separator_8);
+		reloadProjectFromFile();
+		hasGeneFile = findGeneFile();
+
+		ButtonGroup bwaGroup = new ButtonGroup();
+		bwaGroup.add(alreadyInstalledRadio);
+		bwaGroup.add(useScriptsRadio);
+
+		JLabel lblNewLabel_1 = new JLabel(" on your machine .");
+		lblNewLabel_1.setBounds(20, 58, 246, 15);
+		panel_3.add(lblNewLabel_1);
+		remoteHelpBtn.setToolTipText("Help for creating a SAM file on your remote Linux machine");
+
+		remoteHelpBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				remoteInstallHelp();
+			}
+		});
+		remoteHelpBtn.setBounds(10, 374, 256, 25);
+		panel_3.add(remoteHelpBtn);
+
+		JPanel panel_5 = new JPanel();
+		panel_5.setBounds(10, 179, 803, 183);
+		panel_3.add(panel_5);
+		GridBagLayout gbl_panel_5 = new GridBagLayout();
+		gbl_panel_5.columnWidths = new int[]{0, 461, 85, 0};
+		gbl_panel_5.rowHeights = new int[]{0, 0, 0, 0, 0, 0};
+		gbl_panel_5.columnWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
+		gbl_panel_5.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
+		panel_5.setLayout(gbl_panel_5);
+
+		JLabel lblSelectThefastq = new JLabel("Select the 'FASTQ' File:");
+		GridBagConstraints gbc_lblSelectThefastq = new GridBagConstraints();
+		gbc_lblSelectThefastq.anchor = GridBagConstraints.WEST;
+		gbc_lblSelectThefastq.insets = new Insets(0, 0, 5, 5);
+		gbc_lblSelectThefastq.gridx = 0;
+		gbc_lblSelectThefastq.gridy = 0;
+		panel_5.add(lblSelectThefastq, gbc_lblSelectThefastq);
+
+		fastqFilePath = new JTextField();
+		GridBagConstraints gbc_fastqFilePath = new GridBagConstraints();
+		gbc_fastqFilePath.fill = GridBagConstraints.HORIZONTAL;
+		gbc_fastqFilePath.insets = new Insets(0, 0, 5, 5);
+		gbc_fastqFilePath.gridx = 1;
+		gbc_fastqFilePath.gridy = 0;
+		panel_5.add(fastqFilePath, gbc_fastqFilePath);
+		fastqFilePath.setText("");
+		fastqFilePath.setEnabled(true);
+		fastqFilePath.setEditable(false);
+		fastqFilePath.setColumns(10);
+
+		JButton fastqBrowseBtn = new JButton("Browse");
+		GridBagConstraints gbc_fastqBrowseBtn = new GridBagConstraints();
+		gbc_fastqBrowseBtn.fill = GridBagConstraints.HORIZONTAL;
+		gbc_fastqBrowseBtn.insets = new Insets(0, 0, 5, 0);
+		gbc_fastqBrowseBtn.gridx = 2;
+		gbc_fastqBrowseBtn.gridy = 0;
+		panel_5.add(fastqBrowseBtn, gbc_fastqBrowseBtn);
+		fastqBrowseBtn.setToolTipText("Select a FASTQ file");
+
+		JLabel lblSelectThefna = new JLabel("Select the 'FNA' File:");
+		GridBagConstraints gbc_lblSelectThefna = new GridBagConstraints();
+		gbc_lblSelectThefna.anchor = GridBagConstraints.WEST;
+		gbc_lblSelectThefna.insets = new Insets(0, 0, 5, 5);
+		gbc_lblSelectThefna.gridx = 0;
+		gbc_lblSelectThefna.gridy = 1;
+		panel_5.add(lblSelectThefna, gbc_lblSelectThefna);
+
+		fnaFilePath = new JTextField();
+		fnaFilePath.setEditable(false);
+		GridBagConstraints gbc_fnaFilePath = new GridBagConstraints();
+		gbc_fnaFilePath.insets = new Insets(0, 0, 5, 5);
+		gbc_fnaFilePath.fill = GridBagConstraints.HORIZONTAL;
+		gbc_fnaFilePath.gridx = 1;
+		gbc_fnaFilePath.gridy = 1;
+		panel_5.add(fnaFilePath, gbc_fnaFilePath);
+		fnaFilePath.setColumns(10);
+
+		JButton fnaBrowseBtn = new JButton("Browse");
+		GridBagConstraints gbc_fnaBrowseBtn = new GridBagConstraints();
+		gbc_fnaBrowseBtn.fill = GridBagConstraints.HORIZONTAL;
+		gbc_fnaBrowseBtn.insets = new Insets(0, 0, 5, 0);
+		gbc_fnaBrowseBtn.gridx = 2;
+		gbc_fnaBrowseBtn.gridy = 1;
+		panel_5.add(fnaBrowseBtn, gbc_fnaBrowseBtn);
+		fnaBrowseBtn.setToolTipText("Select a FNA file");
+		fnaBrowseBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				@SuppressWarnings("unused")
+				SelectFNA fna = new SelectFNA(projectInfo, MainFrame.this, fnaFilePath);
+				MainFrame.this.setVisible(false);
+			}
+		});
+
+		JLabel lblCreateSamFile = new JLabel("Create SAM file in:");
+		GridBagConstraints gbc_lblCreateSamFile = new GridBagConstraints();
+		gbc_lblCreateSamFile.anchor = GridBagConstraints.WEST;
+		gbc_lblCreateSamFile.insets = new Insets(0, 0, 5, 5);
+		gbc_lblCreateSamFile.gridx = 0;
+		gbc_lblCreateSamFile.gridy = 2;
+		panel_5.add(lblCreateSamFile, gbc_lblCreateSamFile);
+
+		samFilePath = new JTextField();
+		GridBagConstraints gbc_samFilePath = new GridBagConstraints();
+		gbc_samFilePath.fill = GridBagConstraints.HORIZONTAL;
+		gbc_samFilePath.insets = new Insets(0, 0, 5, 5);
+		gbc_samFilePath.gridx = 1;
+		gbc_samFilePath.gridy = 2;
+		panel_5.add(samFilePath, gbc_samFilePath);
+		samFilePath.setText("");
+		samFilePath.setEnabled(true);
+		samFilePath.setEditable(false);
+		samFilePath.setColumns(10);
+
+		JButton newSamBrowseBtn = new JButton("Browse");
+		GridBagConstraints gbc_newSamBrowseBtn = new GridBagConstraints();
+		gbc_newSamBrowseBtn.fill = GridBagConstraints.HORIZONTAL;
+		gbc_newSamBrowseBtn.insets = new Insets(0, 0, 5, 0);
+		gbc_newSamBrowseBtn.gridx = 2;
+		gbc_newSamBrowseBtn.gridy = 2;
+		panel_5.add(newSamBrowseBtn, gbc_newSamBrowseBtn);
+		newSamBrowseBtn.setToolTipText("Select a location to save the new SAM file");
+
+		JLabel lblEnterNewSam = new JLabel("Enter new SAM file name:");
+		GridBagConstraints gbc_lblEnterNewSam = new GridBagConstraints();
+		gbc_lblEnterNewSam.anchor = GridBagConstraints.WEST;
+		gbc_lblEnterNewSam.insets = new Insets(0, 0, 5, 5);
+		gbc_lblEnterNewSam.gridx = 0;
+		gbc_lblEnterNewSam.gridy = 3;
+		panel_5.add(lblEnterNewSam, gbc_lblEnterNewSam);
+
+		newSamNameTxt = new JTextField();
+		GridBagConstraints gbc_newSamNameTxt = new GridBagConstraints();
+		gbc_newSamNameTxt.fill = GridBagConstraints.HORIZONTAL;
+		gbc_newSamNameTxt.insets = new Insets(0, 0, 5, 5);
+		gbc_newSamNameTxt.gridx = 1;
+		gbc_newSamNameTxt.gridy = 3;
+		panel_5.add(newSamNameTxt, gbc_newSamNameTxt);
+		newSamNameTxt.addFocusListener(new FocusAdapter() {
+			@Override
+			public void focusGained(FocusEvent arg0) {
+				highlightAllTheText((JTextField) arg0.getComponent());
+			}
+		});
+		newSamNameTxt.setToolTipText("Created SAM file name");
+		newSamNameTxt.setText("");
+		newSamNameTxt.setEnabled(true);
+		newSamNameTxt.setColumns(10);
+
+		JLabel label_4 = new JLabel("(?)");
+		GridBagConstraints gbc_label_4 = new GridBagConstraints();
+		gbc_label_4.anchor = GridBagConstraints.WEST;
+		gbc_label_4.insets = new Insets(0, 0, 0, 5);
+		gbc_label_4.gridx = 0;
+		gbc_label_4.gridy = 4;
+		panel_5.add(label_4, gbc_label_4);
+		label_4.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				JOptionPane.showMessageDialog(MainFrame.this, "The FASTQ file contains your sequence reads and you should have received it from Illumina or the sequencing facility\n"
+						+ "you used. The FNA file contains the genomic DNA sequence in fastA format and you can download it for complete\n"
+						+ "prokaryotic genomes from the NCBI ftp server at ftp://ftp.ncbi.nih.gov/genomes/archive/old_genbank/Bacteria/");
+			}
+		});
+		label_4.setToolTipText("Click me!");
+		label_4.setForeground(Color.BLUE);
+		label_4.setFont(new Font("Tahoma", Font.PLAIN, 11));
+
+		JButton btnRun = new JButton("Create SAM file");
+		GridBagConstraints gbc_btnRun = new GridBagConstraints();
+		gbc_btnRun.gridx = 2;
+		gbc_btnRun.gridy = 4;
+		panel_5.add(btnRun, gbc_btnRun);
+		btnRun.setToolTipText("Create the SAM file");
+		btnRun.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				try {
+					createSamFile();
+				} catch (InterruptedException e1) {
+					e1.printStackTrace();
+				} catch (IOException e2) {
+					e2.printStackTrace();
+				}
+			}
+		});
+		newSamBrowseBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath()
+						.toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+				int result = fileChooser.showOpenDialog(MainFrame.this);
+
+				if (result == JFileChooser.APPROVE_OPTION){
+					samFilePath.setText(fileChooser.getSelectedFile().getAbsolutePath());
+				}else{
+					return;
+				}
+			}
+		});
+		fastqBrowseBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath()
+						.toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+				fileChooser.setFileFilter(new FileNameExtensionFilter("FASTQ Files (.fastq)", "fastq"));
+				int result = fileChooser.showOpenDialog(MainFrame.this);
+
+				if (result == JFileChooser.APPROVE_OPTION){
+					fastqFilePath.setText(fileChooser.getSelectedFile().getAbsolutePath());
+				}else{
+					return;
+				}
+			}
+		});
+
+		JPanel panel_1 = new JPanel();
+		tabbedPane.addTab("Bowtie2", null, panel_1, null);
+		panel_1.setLayout(null);
+
+		JPanel panel_2 = new JPanel();
+		panel_2.setBounds(12, 12, 801, 25);
+		panel_1.add(panel_2);
+		panel_2.setLayout(null);
+
+		JPanel panel_4 = new JPanel();
+		panel_4.setBounds(12, 63, 799, 192);
+		panel_1.add(panel_4);
+		GridBagLayout gbl_panel_4 = new GridBagLayout();
+		gbl_panel_4.columnWidths = new int[]{0, 0, 0, 0};
+		gbl_panel_4.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0};
+		gbl_panel_4.columnWeights = new double[]{0.0, 1.0, 0.0, Double.MIN_VALUE};
+		gbl_panel_4.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
+		panel_4.setLayout(gbl_panel_4);
+
+		JLabel lblFastqFile = new JLabel("FastQ File");
+		GridBagConstraints gbc_lblFastqFile = new GridBagConstraints();
+		gbc_lblFastqFile.anchor = GridBagConstraints.WEST;
+		gbc_lblFastqFile.insets = new Insets(0, 0, 5, 5);
+		gbc_lblFastqFile.gridx = 0;
+		gbc_lblFastqFile.gridy = 0;
+		panel_4.add(lblFastqFile, gbc_lblFastqFile);
+
+		bowtieFastqTxt = new JTextField();
+		bowtieFastqTxt.setEditable(false);
+		GridBagConstraints gbc_bowtieFastqTxt = new GridBagConstraints();
+		gbc_bowtieFastqTxt.insets = new Insets(0, 0, 5, 5);
+		gbc_bowtieFastqTxt.fill = GridBagConstraints.HORIZONTAL;
+		gbc_bowtieFastqTxt.gridx = 1;
+		gbc_bowtieFastqTxt.gridy = 0;
+		panel_4.add(bowtieFastqTxt, gbc_bowtieFastqTxt);
+		bowtieFastqTxt.setColumns(10);
+
+		JButton bowtieFastqBrowse = new JButton("Browse");
+		bowtieFastqBrowse.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath().toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+				fileChooser.setFileFilter(new FileNameExtensionFilter("FASTQ Files (.fastq)", "fastq"));
+				int result = fileChooser.showOpenDialog(MainFrame.this);
+
+				if (result == JFileChooser.APPROVE_OPTION){
+					bowtieFastqTxt.setText(fileChooser.getSelectedFile().getAbsolutePath());
+				}else{
+					return;
+				}
+			}
+		});
+		GridBagConstraints gbc_bowtieFastqBrowse = new GridBagConstraints();
+		gbc_bowtieFastqBrowse.fill = GridBagConstraints.HORIZONTAL;
+		gbc_bowtieFastqBrowse.insets = new Insets(0, 0, 5, 0);
+		gbc_bowtieFastqBrowse.gridx = 2;
+		gbc_bowtieFastqBrowse.gridy = 0;
+		panel_4.add(bowtieFastqBrowse, gbc_bowtieFastqBrowse);
+
+		JLabel lblFna = new JLabel("FNA");
+		GridBagConstraints gbc_lblFna = new GridBagConstraints();
+		gbc_lblFna.anchor = GridBagConstraints.WEST;
+		gbc_lblFna.insets = new Insets(0, 0, 5, 5);
+		gbc_lblFna.gridx = 0;
+		gbc_lblFna.gridy = 1;
+		panel_4.add(lblFna, gbc_lblFna);
+
+		bowtieFnaTxt = new JTextField();
+		bowtieFnaTxt.setEditable(false);
+		GridBagConstraints gbc_bowtieFnaTxt = new GridBagConstraints();
+		gbc_bowtieFnaTxt.insets = new Insets(0, 0, 5, 5);
+		gbc_bowtieFnaTxt.fill = GridBagConstraints.HORIZONTAL;
+		gbc_bowtieFnaTxt.gridx = 1;
+		gbc_bowtieFnaTxt.gridy = 1;
+		panel_4.add(bowtieFnaTxt, gbc_bowtieFnaTxt);
+		bowtieFnaTxt.setColumns(10);
+
+		JButton bowtieFnaBrowse = new JButton("Browse");
+		bowtieFnaBrowse.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {					
+				@SuppressWarnings("unused")
+				SelectFNA fna = new SelectFNA(projectInfo, MainFrame.this, bowtieFnaTxt);
+				MainFrame.this.setVisible(false);
+			}
+		});
+		GridBagConstraints gbc_bowtieFnaBrowse = new GridBagConstraints();
+		gbc_bowtieFnaBrowse.fill = GridBagConstraints.HORIZONTAL;
+		gbc_bowtieFnaBrowse.insets = new Insets(0, 0, 5, 0);
+		gbc_bowtieFnaBrowse.gridx = 2;
+		gbc_bowtieFnaBrowse.gridy = 1;
+		panel_4.add(bowtieFnaBrowse, gbc_bowtieFnaBrowse);
+
+		JLabel lblMinimumScore = new JLabel("Options");
+		GridBagConstraints gbc_lblMinimumScore = new GridBagConstraints();
+		gbc_lblMinimumScore.anchor = GridBagConstraints.WEST;
+		gbc_lblMinimumScore.insets = new Insets(0, 0, 5, 5);
+		gbc_lblMinimumScore.gridx = 0;
+		gbc_lblMinimumScore.gridy = 2;
+		panel_4.add(lblMinimumScore, gbc_lblMinimumScore);
+
+		bowtieMinScore = new JTextField();
+		bowtieMinScore.setText("-L 20 -N 0 --score-min L,-0.6,-0.6");
+		GridBagConstraints gbc_bowtieMinScore = new GridBagConstraints();
+		gbc_bowtieMinScore.anchor = GridBagConstraints.WEST;
+		gbc_bowtieMinScore.insets = new Insets(0, 0, 5, 5);
+		gbc_bowtieMinScore.gridx = 1;
+		gbc_bowtieMinScore.gridy = 2;
+		panel_4.add(bowtieMinScore, gbc_bowtieMinScore);
+		bowtieMinScore.setColumns(25);
+
+		JLabel label_12 = new JLabel("(?)");
+		label_12.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				//TODO: Fill this message here!
+				JOptionPane.showMessageDialog(MainFrame.this, "You can change the Bowtie2 options using this textbox.\n"
+						+ "For more details please visit: \"http://bowtie-bio.sourceforge.net/bowtie2/manual.shtml#options\"");
+			}
+		});
+		label_12.setForeground(Color.BLUE);
+		GridBagConstraints gbc_label_12 = new GridBagConstraints();
+		gbc_label_12.anchor = GridBagConstraints.WEST;
+		gbc_label_12.insets = new Insets(0, 0, 5, 0);
+		gbc_label_12.gridx = 2;
+		gbc_label_12.gridy = 2;
+		panel_4.add(label_12, gbc_label_12);
+		label_12.setToolTipText("Click me!");
+		label_12.setForeground(Color.BLUE);
+		label_12.setFont(new Font("Tahoma", Font.PLAIN, 11));
+
+		JLabel lblSamFile = new JLabel("SAM file location");
+		GridBagConstraints gbc_lblSamFile = new GridBagConstraints();
+		gbc_lblSamFile.anchor = GridBagConstraints.WEST;
+		gbc_lblSamFile.insets = new Insets(0, 0, 5, 5);
+		gbc_lblSamFile.gridx = 0;
+		gbc_lblSamFile.gridy = 3;
+		panel_4.add(lblSamFile, gbc_lblSamFile);
+
+		bowtieSamLocTxt = new JTextField();
+		bowtieSamLocTxt.setEditable(false);
+		GridBagConstraints gbc_bowtieSamLocTxt = new GridBagConstraints();
+		gbc_bowtieSamLocTxt.fill = GridBagConstraints.HORIZONTAL;
+		gbc_bowtieSamLocTxt.insets = new Insets(0, 0, 5, 5);
+		gbc_bowtieSamLocTxt.gridx = 1;
+		gbc_bowtieSamLocTxt.gridy = 3;
+		panel_4.add(bowtieSamLocTxt, gbc_bowtieSamLocTxt);
+		bowtieSamLocTxt.setColumns(10);
+
+		JButton bowtieSamBrowseBtn = new JButton("Browse");
+		bowtieSamBrowseBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath().toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+				int result = fileChooser.showOpenDialog(MainFrame.this);
+
+				if (result == JFileChooser.APPROVE_OPTION){
+					bowtieSamLocTxt.setText(fileChooser.getSelectedFile().getAbsolutePath());
+					
+					File sam_loc = new File(projectInfo.getPath() + "sam_loc");
+					try{
+						BufferedWriter bw = new BufferedWriter(new FileWriter(sam_loc));
+						bw.write(fileChooser.getSelectedFile().getAbsolutePath());
+						bw.close();
+					}catch (IOException e){
+						e.printStackTrace();
+					}
+					
+				}else{
+					return;
+				}
+			}
+		});
+		GridBagConstraints gbc_bowtieSamBrowseBtn = new GridBagConstraints();
+		gbc_bowtieSamBrowseBtn.fill = GridBagConstraints.BOTH;
+		gbc_bowtieSamBrowseBtn.insets = new Insets(0, 0, 5, 0);
+		gbc_bowtieSamBrowseBtn.gridx = 2;
+		gbc_bowtieSamBrowseBtn.gridy = 3;
+		panel_4.add(bowtieSamBrowseBtn, gbc_bowtieSamBrowseBtn);
+
+		JLabel lblSamFilename = new JLabel("SAM filename");
+		GridBagConstraints gbc_lblSamFilename = new GridBagConstraints();
+		gbc_lblSamFilename.anchor = GridBagConstraints.WEST;
+		gbc_lblSamFilename.insets = new Insets(0, 0, 5, 5);
+		gbc_lblSamFilename.gridx = 0;
+		gbc_lblSamFilename.gridy = 4;
+		panel_4.add(lblSamFilename, gbc_lblSamFilename);
+
+		bowtieSamFilenameTxt = new JTextField();
+		GridBagConstraints gbc_bowtieSamFilenameTxt = new GridBagConstraints();
+		gbc_bowtieSamFilenameTxt.anchor = GridBagConstraints.WEST;
+		gbc_bowtieSamFilenameTxt.insets = new Insets(0, 0, 5, 5);
+		gbc_bowtieSamFilenameTxt.gridx = 1;
+		gbc_bowtieSamFilenameTxt.gridy = 4;
+		panel_4.add(bowtieSamFilenameTxt, gbc_bowtieSamFilenameTxt);
+		bowtieSamFilenameTxt.setColumns(15);
+
+		bowtieSamCreateBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent e) {
+				try {
+					BowtieCreateSam();
+				} catch (IOException e1) {
+					e1.printStackTrace();
+				}
+			}
+		});
+		GridBagConstraints gbc_bowtieSamCreateBtn = new GridBagConstraints();
+		gbc_bowtieSamCreateBtn.fill = GridBagConstraints.HORIZONTAL;
+		gbc_bowtieSamCreateBtn.gridx = 2;
+		gbc_bowtieSamCreateBtn.gridy = 5;
+		panel_4.add(bowtieSamCreateBtn, gbc_bowtieSamCreateBtn);
+
+		JSeparator separator_11 = new JSeparator();
+		separator_11.setBounds(12, 48, 823, 2);
+		panel_1.add(separator_11);
+
+		if(!hasSeqNum  || !hasGeneFile){
+			for (int i = 1; i < tabbedPane.getTabCount(); i++){
+				tabbedPane.setEnabledAt(i, false);
+			}
+		}else{
+			infoLbl.setVisible(false);
+		}
+	}
+
+	private void BowtieCreateSam() throws IOException{
+		final String OSName = System.getProperty("os.name");
+
+		String bowtie2_build = "bowtie2-build";
+		String bowtie2 = "bowtie2";
+
+		File bowtie_index = null;
+		File bowtie_align = null;
+
+		if(OSName.toLowerCase().contains("win")){
+			String tempPath = System.getProperty("java.io.tmpdir");
+			if (!tempPath.endsWith(File.separator)){
+				tempPath = tempPath + File.separator;
+			}
+
+			bowtie2_build = bowtie2_build + ".exe";
+			bowtie2 = bowtie2 + ".exe";
+
+			bowtie_index = new File(tempPath + bowtie2_build);
+			bowtie_align = new File(tempPath + bowtie2);
+
+			URL indexer = MainFrame.class.getResource("/resources/bowtie-bin/win-64/bowtie2-build-s.exe");
+			URL aligner = MainFrame.class.getResource("/resources/bowtie-bin/win-64/bowtie2-align-s.exe");
+
+			FileUtils.copyURLToFile(indexer, bowtie_index);
+			FileUtils.copyURLToFile(aligner, bowtie_align);
+		}else if (OSName.toLowerCase().contains("mac")){
+			String tempPath = "bowtie-bin/"; 
+
+			bowtie_index = new File(tempPath + bowtie2_build);
+			bowtie_align = new File(tempPath + bowtie2);
+
+			URL indexer = MainFrame.class.getResource("/resources/bowtie-bin/mac/bowtie2-build");
+			URL aligner = MainFrame.class.getResource("/resources/bowtie-bin/mac/bowtie2");
+
+			FileUtils.copyURLToFile(indexer, bowtie_index);
+			FileUtils.copyURLToFile(aligner, bowtie_align);
+
+			Runtime.getRuntime().exec("chmod 777 " + bowtie_index.getAbsolutePath());
+			Runtime.getRuntime().exec("chmod 777 " + bowtie_align.getAbsolutePath());
+
+			String name = "bowtie2-align-l";
+			File temp_f = new File(tempPath + name);
+			URL temp_u = MainFrame.class.getResource("/resources/bowtie-bin/mac/" + name);
+			FileUtils.copyURLToFile(temp_u, temp_f);
+			Runtime.getRuntime().exec("chmod 777 " + temp_f.getAbsolutePath());
+
+			name = "bowtie2-align-s";
+			temp_f = new File(tempPath + name);
+			temp_u = MainFrame.class.getResource("/resources/bowtie-bin/mac/" + name);
+			FileUtils.copyURLToFile(temp_u, temp_f);
+			Runtime.getRuntime().exec("chmod 777 " + temp_f.getAbsolutePath());
+
+			name = "bowtie2-build-l";
+			temp_f = new File(tempPath + name);
+			temp_u = MainFrame.class.getResource("/resources/bowtie-bin/mac/" + name);
+			FileUtils.copyURLToFile(temp_u, temp_f);
+			Runtime.getRuntime().exec("chmod 777 " + temp_f.getAbsolutePath());
+
+			name = "bowtie2-build-s";
+			temp_f = new File(tempPath + name);
+			temp_u = MainFrame.class.getResource("/resources/bowtie-bin/mac/" + name);
+			FileUtils.copyURLToFile(temp_u, temp_f);
+			Runtime.getRuntime().exec("chmod 777 " + temp_f.getAbsolutePath());
+		}else{
+			String tempPath = "bowtie-bin/"; 
+
+			bowtie_index = new File(tempPath + bowtie2_build);
+			bowtie_align = new File(tempPath + bowtie2);
+
+			URL indexer = MainFrame.class.getResource("/resources/bowtie-bin/linux/bowtie2-build");
+			URL aligner = MainFrame.class.getResource("/resources/bowtie-bin/linux/bowtie2");
+
+			FileUtils.copyURLToFile(indexer, bowtie_index);
+			FileUtils.copyURLToFile(aligner, bowtie_align);
+
+			Runtime.getRuntime().exec("chmod 777 " + bowtie_index.getAbsolutePath());
+			Runtime.getRuntime().exec("chmod 777 " + bowtie_align.getAbsolutePath());
+
+			String name = "bowtie2-align-l";
+			File temp_f = new File(tempPath + name);
+			URL temp_u = MainFrame.class.getResource("/resources/bowtie-bin/linux/" + name);
+			FileUtils.copyURLToFile(temp_u, temp_f);
+			Runtime.getRuntime().exec("chmod 777 " + temp_f.getAbsolutePath());
+
+			name = "bowtie2-align-s";
+			temp_f = new File(tempPath + name);
+			temp_u = MainFrame.class.getResource("/resources/bowtie-bin/linux/" + name);
+			FileUtils.copyURLToFile(temp_u, temp_f);
+			Runtime.getRuntime().exec("chmod 777 " + temp_f.getAbsolutePath());
+
+			name = "bowtie2-build-l";
+			temp_f = new File(tempPath + name);
+			temp_u = MainFrame.class.getResource("/resources/bowtie-bin/linux/" + name);
+			FileUtils.copyURLToFile(temp_u, temp_f);
+			Runtime.getRuntime().exec("chmod 777 " + temp_f.getAbsolutePath());
+
+			name = "bowtie2-build-s";
+			temp_f = new File(tempPath + name);
+			temp_u = MainFrame.class.getResource("/resources/bowtie-bin/linux/" + name);
+			FileUtils.copyURLToFile(temp_u, temp_f);
+			Runtime.getRuntime().exec("chmod 777 " + temp_f.getAbsolutePath());
+		}
+
+		String bowtie_align_options = "-q"; 
+
+		if (bowtie_align == null || bowtie_index == null){
+			JOptionPane.showMessageDialog(this, "Bowtie is not supported on this platform within Tn-SeqExplorer.\n"
+					+ "Please use either Microsoft Window (64bit) or any distribution of Linux operating systems.");
+			return;
+		}
+
+		if (bowtie_index.exists() && bowtie_align.exists()){
+			String fnaPath = bowtieFnaTxt.getText();
+			String fastQPath = bowtieFastqTxt.getText();
+			String samLoc = bowtieSamLocTxt.getText();
+			String samName = bowtieSamFilenameTxt.getText();
+			String minScore = bowtieMinScore.getText();
+
+			if (fnaPath == null || fnaPath.equals("")){
+				JOptionPane.showMessageDialog(this, "Please fill out all the fields.");
+				return;
+			}
+
+			if (fastQPath == null || fastQPath.equals("")){
+				JOptionPane.showMessageDialog(this, "Please fill out all the fields.");
+				return;
+			}
+
+			if (samLoc == null || samLoc.equals("")){
+				JOptionPane.showMessageDialog(this, "Please fill out all the fields.");
+				return;
+			}
+
+			if (samName == null || samName.equals("")){
+				JOptionPane.showMessageDialog(this, "Please fill out all the fields.");
+				return;
+			}
+
+			if (minScore == null || minScore.equals("")) {
+				minScore = "";
+			} else {
+				bowtie_align_options = String.format("%s %s", bowtie_align_options, minScore);
+			}
+
+			if (!samLoc.endsWith(File.separator)){
+				samLoc = samLoc + File.separator; 
+			}
+
+			String index_file = samLoc + samName + "_index";
+			final String sam_file = samLoc + samName + ".sam";
+			final String location_temp = samLoc;
+
+			final String script_index = String.format("%s \"%s\" \"%s\"", bowtie_index.getAbsolutePath(), fnaPath, index_file);
+			final String script_align = String.format("%s %s -x \"%s\" -U \"%s\" -S \"%s\"", bowtie_align.getAbsolutePath(), bowtie_align_options, index_file, fastQPath, sam_file);
+
+			final String script_index_linux = String.format("%s %s %s", bowtie_index.getAbsolutePath(), fnaPath, index_file);
+			final String script_align_linux = String.format("%s %s -x %s -U %s -S %s", bowtie_align.getAbsolutePath(), bowtie_align_options, index_file, fastQPath, sam_file);
+
+			JOptionPane.showMessageDialog(this, "Creating the SAM file might take a few minutes, please be patient!\n\n "
+					+ "Make sure that there is no Space character present in the FASTQ file's path.");
+			bowtieSamCreateBtn.setText("Please wait...");
+			bowtieSamCreateBtn.setEnabled(false);
+			final Icon tempIcon = bowtieSamCreateBtn.getIcon();
+			bowtieSamCreateBtn.setIcon(new ImageIcon(MainFrame.class.getResource("/resources/load.gif")));
+
+			new Thread(new Runnable() {
+				@Override
+				public void run() {
+					boolean success = true;
+					StringBuilder indexerMSG = new StringBuilder();
+					StringBuilder builderMSG = new StringBuilder();
+					String msg = "SAM file created!";
+					try{						
+						if (OSName.toLowerCase().contains("win")){
+
+							boolean if64 = false;
+							{
+								Process win_ver_check = null;
+								ProcessBuilder builder_temp = new ProcessBuilder("cmd.exe", "/c", "wmic os get osarchitecture");
+								builder_temp.redirectErrorStream(true);
+								win_ver_check = builder_temp.start();
+
+								BufferedReader r = new BufferedReader(new InputStreamReader(win_ver_check.getInputStream()));
+								String line;
+								while (true) {
+									line = r.readLine();
+									if (line == null) { break; }
+									if (line.toLowerCase().contains("64")){
+										if64 = true;
+										break;
+									}
+								}
+							}
+							
+							if (!if64){
+								JOptionPane.showMessageDialog(MainFrame.this, "Bowtie2 runs only on 64 bits version of Windows");
+								File folder = new File(location_temp);
+								File[] listOfFiles = folder.listFiles();
+								for (int i = 0; i < listOfFiles.length; i++) {
+									if (listOfFiles[i].isFile()) {
+										if (listOfFiles[i].getName().toLowerCase().contains("_index") || listOfFiles[i].getName().toLowerCase().endsWith("bt2")){
+											listOfFiles[i].delete();
+										}	
+									}
+								}
+
+								bowtieSamCreateBtn.setIcon(tempIcon);
+								bowtieSamCreateBtn.setText("Create SAM file");
+								bowtieSamCreateBtn.setEnabled(true);
+								return;
+							}
+
+							Process index_p = null;
+
+							ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", script_index);
+							builder.redirectErrorStream(true);
+							index_p = builder.start();
+
+							BufferedReader r = new BufferedReader(new InputStreamReader(index_p.getInputStream()));
+							String line;
+							while (true) {
+								line = r.readLine();
+								if (line == null) { break; }
+
+								indexerMSG.append(line + "\n");
+
+								if (line.toLowerCase().contains("error")){
+									success = false;
+									msg = line;
+									break;
+								}
+							}
+
+							try {
+								index_p.waitFor();
+							} catch (InterruptedException e) {
+								e.printStackTrace();
+							}
+
+							builder = new ProcessBuilder("cmd.exe", "/c", script_align);
+							builder.redirectErrorStream(true);
+							index_p = builder.start();
+
+							r = new BufferedReader(new InputStreamReader(index_p.getInputStream()));
+							while (true) {
+								line = r.readLine();
+								if (line == null) { break; }
+
+								builderMSG.append(line + "\n");
+
+								if (line.toLowerCase().contains("error")){
+									success = false;
+									msg = line;
+									break;
+								}
+							}
+
+							try {
+								index_p.waitFor();
+							} catch (InterruptedException e) {
+								e.printStackTrace();
+							}
+
+						}else{	
+
+							///////////////////////////////////////////////////////////////////////////////
+
+							Process index_p = null;
+							index_p = Runtime.getRuntime().exec(script_index_linux);
+
+							BufferedReader r = new BufferedReader(new InputStreamReader(index_p.getInputStream()));
+							String line;
+							while (true) {
+								line = r.readLine();
+								if (line == null) { break; }
+
+								indexerMSG.append(line + "\n");
+
+								if (line.toLowerCase().contains("error")){
+									success = false;
+									msg = line;
+									break;
+								}
+							}
+
+							boolean process_exited = false;
+							while(!process_exited){
+								try{
+									index_p.exitValue();
+									process_exited = true;
+								}catch(Exception e){
+									process_exited = false;
+								}
+							}
+
+							Process align_p = null;
+							align_p = Runtime.getRuntime().exec(script_align_linux);
+							System.out.println(script_align_linux);
+
+							r = new BufferedReader(new InputStreamReader(align_p.getInputStream()));
+							while (true) {
+								line = r.readLine();
+								if (line == null) { break; }
+
+								indexerMSG.append(line + "\n");
+
+								if (line.toLowerCase().contains("error")){
+									success = false;
+									msg = line;
+									break;
+								}
+							}
+
+							process_exited = false;
+							while(!process_exited){
+								try{
+									align_p.exitValue();
+									process_exited = true;
+								}catch(Exception e){
+									process_exited = false;
+								}
+							}		
+						}
+					}catch(IOException e){
+						e.printStackTrace();
+					}
+
+					File sam_file_f = new File(sam_file);
+					if (!sam_file_f.exists()){
+						success = false;
+						msg = "SAM file does not exist due to an unknown error.";
+					}
+
+					if (sam_file_f.length() == 0){
+						success = false;
+						msg = "SAM file size is 0 due to an unknown error."; 
+					}
+
+					try{
+						if (success){
+							JOptionPane.showMessageDialog(MainFrame.this, msg);
+						}else{
+							String temp_msg = "SAM file creation faild due to the following error:\n" + msg + "\n\n Do you want to save the Bowtie2 error log?";
+							int option = JOptionPane.showConfirmDialog(MainFrame.this, temp_msg, "Error", JOptionPane.YES_NO_OPTION);
+
+							if (option == JOptionPane.YES_OPTION){
+								Path currentRelativePath = Paths.get("");
+								String location = currentRelativePath.toAbsolutePath().toString();
+								JFileChooser fileChooser = new JFileChooser(location);
+
+								int result = fileChooser.showSaveDialog(MainFrame.this);
+
+								if (result == JFileChooser.APPROVE_OPTION){
+									File output = fileChooser.getSelectedFile();
+									BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+
+									bw.write("========================\nIndexer log:\n\n");
+									bw.write(indexerMSG.toString());
+
+									bw.write("\n\n========================\nBuilder log:\n\n");
+									bw.write(builderMSG.toString());
+
+									bw.close();
+
+									JOptionPane.showMessageDialog(MainFrame.this, "Log file saved in\n" + output.getAbsolutePath());
+
+								}else{
+									JOptionPane.showMessageDialog(MainFrame.this, "Faild to save the log file.");
+									return;
+								}
+							}
+						}
+					}catch(IOException e){
+						e.printStackTrace();
+					}
+
+					///// Delete TempFiles
+					File folder = new File(location_temp);
+					File[] listOfFiles = folder.listFiles();
+					for (int i = 0; i < listOfFiles.length; i++) {
+						if (listOfFiles[i].isFile()) {
+							if (listOfFiles[i].getName().toLowerCase().contains("_index") || listOfFiles[i].getName().toLowerCase().endsWith("bt2")){
+								listOfFiles[i].delete();
+							}	
+						}
+					}
+
+					bowtieSamCreateBtn.setIcon(tempIcon);
+					bowtieSamCreateBtn.setText("Create SAM file");
+					bowtieSamCreateBtn.setEnabled(true);					
+
+				}
+			}).start();
+
+		}else{
+			JOptionPane.showMessageDialog(null, "Bowtie binary files don't exist.\n"
+					+ "Please download bowtie2 binary files from \"http://bowtie-bio.sourceforge.net/bowtie2/index.shtml\"\n"
+					+ "and put them into a folder called bowtie-bin/linux/ right beside the Tn-SeqExplorer executable jar file.");
+		}
+	}
+
+	private void findOptimalWinLength(){
+		if (countAllReadsRadio.isSelected()){
+			int res = JOptionPane.showConfirmDialog(MainFrame.this, "This feature cannot be used when counting all reads.\n"
+					+ "Do you want to continue with unique insertions?", "feature cannot be used", JOptionPane.YES_NO_OPTION);
+
+			if (res == JOptionPane.YES_OPTION){
+				countOnlyUniqueRadio.setSelected(true);
+			}else{
+				return;
+			}
+		}
+
+		(new Thread(new Runnable() {
+
+			@Override
+			public void run() {
+				JOptionPane.showMessageDialog(MainFrame.this, "The calculation might take a few minutes to complete.\nPlease be patient.");
+			}
+		})).start();
+
+		plotWaitLbl.setVisible(true);
+
+		(new Thread(new Runnable() {
+
+			@Override
+			public void run() {
+				try {					
+					Pair<Integer, Integer> result = StatisticsHelper.findOptimalLength((String) plotLibraryCombo.getSelectedItem(), projectInfo, countOnlyUniqueRadio.isSelected(), MainFrame.this);
+
+					changeWinLenTo("Plotting...");
+
+					final String title;
+					if (countOnlyUniqueRadio.isSelected()){
+						String temp = String.format("Library Name: %s (Counting unique insertions) | Window Length: %d | Window Steps: %d", (String) plotLibraryCombo.getSelectedItem(), result.getFirst(), result.getSecond());
+						title = temp;
+					} else{
+						String temp = String.format("Library Name: %s (Counting all reads) | Window Length: %d | Window Steps: %d", (String) plotLibraryCombo.getSelectedItem(), result.getFirst(), result.getSecond());
+						title = temp;
+					}
+
+					ChartPanel panel = new ChartPanel(PlotData.plotData((String) plotLibraryCombo.getSelectedItem(), result.getFirst(), result.getSecond(), title, projectInfo, countOnlyUniqueRadio.isSelected()));
+
+					ExtendedPlotViewer frame = new ExtendedPlotViewer(MainFrame.this);	
+					frame.setWinInfo(result.getFirst(), result.getSecond());
+					frame.setDataFile((String) plotLibraryCombo.getSelectedItem());
+					frame.setPlotName(title);
+					frame.setIfSelected(countOnlyUniqueRadio.isSelected());
+					frame.setProjectInfo(projectInfo);
+					frame.setCurrentInfo(result.getFirst(), result.getSecond());
+					frame.setVisible(true);
+					frame.addPlot(panel);	
+
+					plotWaitLbl.setVisible(false);
+					(MainFrame.this).makeWinlenLblVisible(false);
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		})).start();
+	}
+
+	public void setWinInfoAndSave(int winLen, int winStep){
+		winLenTxt.setText(winLen + "");
+		winStepTxt.setText(winStep + "");
+
+		try{
+			//Save the results to a file
+			File winLenFile = new File(projectInfo.getPath() + (String)plotLibraryCombo.getSelectedItem() + ".data");
+			BufferedWriter bw = new BufferedWriter(new FileWriter(winLenFile));
+			bw.write("WinLen = " + winLen + "\n");
+			bw.write("WinStep = " + winStep + "\n");
+			bw.close();
+		}catch(IOException e){
+			logger.fatal(e.getMessage());
+		}
+	}
+
+	public boolean checkIfApplied(int winLen, int winStep){
+
+		if (winLenTxt.getText().equals("") || winStepTxt.getText().equals("")){
+			return false;
+		}
+
+		if (Integer.parseInt(winLenTxt.getText()) != winLen){
+			return false;
+		}
+
+		if (Integer.parseInt(winStepTxt.getText()) != winStep){
+			return false;
+		}
+
+		return true;
+
+	}
+
+	private void highlightAllTheText(final JTextField textField){
+		SwingUtilities.invokeLater( new Runnable() {
+
+			@Override
+			public void run() {
+				textField.selectAll();		
+			}
+		});	
+	}
+
+	private void maxNumInsrtions(){
+		if(winLenTxt.getText() == null || winLenTxt.getText().compareTo("") == 0){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please provide the window length", "Warning", JOptionPane.WARNING_MESSAGE);
+			return;
+		}
+		if(winStepTxt.getText() == null || winStepTxt.getText().compareTo("") == 0){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please provide the window step length", "Warning", JOptionPane.WARNING_MESSAGE);
+			return;
+		}
+		if(maxNumInsTxt.getText() == null || maxNumInsTxt.getText().compareTo("") == 0){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please provide the maximum number of insertions", "Warning", JOptionPane.WARNING_MESSAGE);
+			return;
+		}
+
+
+
+		plotWaitLbl.setVisible(true);
+
+		(new Thread(new Runnable() {
+			@Override
+			public void run() {
+				try {
+					int len = Integer.parseInt(winLenTxt.getText());
+					int step = Integer.parseInt(winStepTxt.getText());
+					int maxNumIns = Integer.parseInt(maxNumInsTxt.getText());
+					boolean ifOnlyInsertions = countOnlyUniqueRadio.isSelected();
+
+					String result = PrepareFiles.maxNumberOfInsertions((String) plotLibraryCombo.getSelectedItem(), len, step, maxNumIns, ifOnlyInsertions, MainFrame.this.projectInfo);
+
+					if (result.compareTo(Messages.failMsg) != 0){
+						JOptionPane.showMessageDialog(null, "Success");
+					}else{
+						logger.error("There was some error while processing Max Number of Insertions");
+						JOptionPane.showMessageDialog(MainFrame.this, "There was some error while processing Max Number of Insertions", "Error", JOptionPane.ERROR_MESSAGE);
+					}
+
+					plotWaitLbl.setVisible(false);
+				}catch(IOException e){
+					logger.error(e.getStackTrace());
+				}catch (NumberFormatException e) {
+					JOptionPane.showMessageDialog(MainFrame.this, "Please enter valid values for Window Length, Step and Max number of insertions fields.");
+					plotWaitLbl.setVisible(false);
+				}
+			}
+		})).start();
+	}
+
+	private void installBWA() {
+		Process p = null;
+		BufferedReader br = null;
+		try {
+			p = Runtime.getRuntime().exec("uname -a");
+			br = new BufferedReader(new InputStreamReader(p.getInputStream()));
+
+			String line = "";
+			while((line = br.readLine()) != null){
+				if (line.toLowerCase().contains("ubuntu")){
+					installBWAUbuntu();
+				}else{
+					installBWARedHat();
+				}
+				break;
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	private void installBWAUbuntu(){
+		URL programSource = MainFrame.class.getResource("/resources/bwa-0.7.5a.tar.bz2");
+		File programDest = new File(projectInfo.getPath() + "bwa-0.7.5a.tar.bz2");
+
+		URL shellSource = MainFrame.class.getResource("/resources/install-bwa-ubuntu.sh");
+		File shellDest = new File(projectInfo.getPath() + "shell.sh");
+
+		JOptionPane.showMessageDialog(null, "In order to install the library, you should enter your machine's root password.\n"
+				+ "The password is only used to install the library.", "Root Password", JOptionPane.WARNING_MESSAGE);
+
+		try {
+			FileUtils.copyURLToFile(programSource, programDest);
+			FileUtils.copyURLToFile(shellSource, shellDest);
+
+			String shellPath = shellDest.getAbsolutePath().replaceAll("\\s+","\\\\ ");
+			String cmd[] = {"gnome-terminal", "-x", "bash", "-c", 
+					"echo 'Please Enter Your Root Password';"
+							+ "pwd;"
+							+ "su -m root -c 'sh " + shellPath + "';"
+							+ "echo;"
+							+ "echo;"
+							+ "echo 'Press Any Key To Continue...';"
+							+ "read"};
+
+			//Path currentRelativePath = Paths.get("");
+			//String location = currentRelativePath.toAbsolutePath().toString();
+			String location = shellDest.getAbsolutePath().substring(0, shellPath.indexOf("/shell.sh"));
+			File dir = new File(location);
+			Process child = Runtime.getRuntime().exec(cmd, null, dir);
+			child.waitFor();
+		} catch (InterruptedException e1) {
+			logger.error(e1.getMessage());
+			return;
+		} catch(IOException e2){
+			logger.error(e2.getMessage());
+			return;
+		}
+	}
+
+	private void installBWARedHat(){
+		URL programSource = MainFrame.class.getResource("/resources/bwa-0.7.5a.tar.bz2");
+		File programDest = new File(projectInfo.getPath() + "bwa-0.7.5a.tar.bz2");
+
+		URL shellSource = MainFrame.class.getResource("/resources/install-bwa-redhat.sh");
+		File shellDest = new File(projectInfo.getPath() + "shell.sh");
+
+		JOptionPane.showMessageDialog(null, "In order to install the library, you should enter your machine's root password.\n"
+				+ "The password is only used to install the library.", "Root Password", JOptionPane.WARNING_MESSAGE);
+
+		try {
+			FileUtils.copyURLToFile(programSource, programDest);
+			FileUtils.copyURLToFile(shellSource, shellDest);
+
+			String shellPath = shellDest.getAbsolutePath().replaceAll("\\s+","\\\\ ");
+			String cmd[] = {"gnome-terminal", "-x", "bash", "-c", 
+					"echo 'Please Enter Your Root Password';"
+							+ "pwd;"
+							+ "su -m root -c 'sh " + shellPath + "';"
+							+ "echo;"
+							+ "echo;"
+							+ "echo 'Press Any Key To Continue...';"
+							+ "read"};
+
+			//Path currentRelativePath = Paths.get("");
+			//String location = currentRelativePath.toAbsolutePath().toString();
+			String location = shellDest.getAbsolutePath().substring(0, shellPath.indexOf("/shell.sh"));
+			File dir = new File(location);
+			Process child = Runtime.getRuntime().exec(cmd, null, dir);
+			child.waitFor();
+		} catch (InterruptedException e1) {
+			logger.error(e1.getMessage());
+			return;
+		} catch(IOException e2){
+			logger.error(e2.getMessage());
+			return;
+		}
+	}
+
+	private void renameLibrary(String newName, String selectedLib) {
+		if(newName != null && newName.compareTo("") != 0){
+
+			BufferedReader br = null;
+			BufferedWriter bw = null;
+			File tempCopy = null;
+			try {
+				tempCopy = new File(projectInfo.getPath() + "temp.pro");
+				br = new BufferedReader(new FileReader(
+						projectInfo.getFile()));
+				bw = new BufferedWriter(new FileWriter(
+						tempCopy));
+
+				String line = br.readLine();
+				bw.write(line + "\n");
+
+				line = br.readLine();
+				bw.write(line + "\n");
+
+				line = br.readLine();
+				bw.write(line + "\n");
+
+				line = br.readLine();
+				while(line != null){
+					if (selectedLib.compareTo(line.substring(0, line.length() - 6)) == 0){					
+						File temp = new File(projectInfo.getPath() + selectedLib + ".inspo");
+						temp.renameTo(new File(projectInfo.getPath() + newName + ".inspo"));
+						bw.write(newName + ".inspo" + "\n");
+
+						temp = new File(projectInfo.getPath() + selectedLib + ".inspos");
+						temp.renameTo(new File(projectInfo.getPath() + newName + ".inspos"));
+						bw.write(newName + ".inspos" + "\n");
+
+						temp = new File(projectInfo.getPath() + selectedLib + ".inspou");
+						temp.renameTo(new File(projectInfo.getPath() + newName + ".inspou"));
+						bw.write(newName + ".inspou" + "\n");
+
+						temp = new File(projectInfo.getPath() + selectedLib + ".inspous");
+						temp.renameTo(new File(projectInfo.getPath() + newName + ".inspous"));
+						bw.write(newName + ".inspous" + "\n");
+
+						temp = new File(projectInfo.getPath() + selectedLib + ".data");
+						temp.renameTo(new File(projectInfo.getPath() + newName + ".data"));
+
+						br.readLine();
+						br.readLine();
+						br.readLine();
+						line = br.readLine();
+
+					}else{
+						bw.write(line + "\n");
+
+						line = br.readLine();
+						bw.write(line + "\n");
+
+						line = br.readLine();
+						bw.write(line + "\n");
+
+						line = br.readLine();
+						bw.write(line + "\n");
+
+						line = br.readLine();
+					}
+
+				}
+
+			} catch (IOException e) {
+				logger.error(e.getMessage());
+				return;
+			} finally {
+				try {
+					br.close();
+					bw.close();
+				} catch (IOException e) {
+					logger.error(e.getMessage());
+					return;
+				}
+			}
+
+			File pro = projectInfo.getFile();
+			pro.delete();
+			tempCopy.renameTo(pro);
+			initiateLibraryComboBox();
+		}
+	}
+
+	private void createSamFile() throws IOException, InterruptedException{
+
+		String fnafile = fnaFilePath.getText();
+		String fastqFile = fastqFilePath.getText();
+		String samName = newSamNameTxt.getText();
+		String samPath = samFilePath.getText();
+
+		if (fnafile == null || fnafile.compareTo("") == 0){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please select a FNA file.", "FNA File is needed", JOptionPane.ERROR_MESSAGE);
+			return;
+		}
+
+		if (fastqFile == null || fastqFile.compareTo("") == 0){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please select a FASTQ file.", "FASTQ File is needed", JOptionPane.ERROR_MESSAGE);
+			return;
+		}
+
+		if (samName == null || samName.compareTo("") == 0){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please enter the new SAM file's name.", "SAM file name is required", JOptionPane.ERROR_MESSAGE);
+			return;
+		}
+
+		if (samPath == null || samPath.compareTo("") == 0){
+			int result = JOptionPane.showConfirmDialog(MainFrame.this, "Do you want the new SAM file to be created in your project folder?", "No location selected for SAM file", JOptionPane.YES_NO_OPTION);
+
+			if(result == JOptionPane.YES_OPTION){
+				samPath = projectInfo.getPath();
+			}else{
+				return;				
+			}
+		}else{
+			samPath = samPath + "/";
+		}
+
+		String name1 = PrepareFiles.prepareOutputFilePath(fastqFile, projectInfo.getPath(), "");
+		String saiName = PrepareFiles.prepareOutputFilePath(fastqFile, projectInfo.getPath(), ".sai");
+		samName = samPath + samName + ".sam";
+
+		File shellScript = new File(projectInfo.getPath() + "temp.sh");
+		BufferedWriter bw = new BufferedWriter(new FileWriter(shellScript));
+
+		String cmdTemp = String.format("bwa index -p \"%s\" \"%s\"\n", name1, fnafile);
+		bw.write(cmdTemp);
+
+		cmdTemp = String.format("bwa aln -k 2 -n 0.001 -l 18 \"%s\" \"%s\" > \"%s\"\n", name1, fastqFile, saiName);
+		bw.write(cmdTemp);
+
+		cmdTemp = String.format("bwa samse -f \"%s\" \"%s\" \"%s\" \"%s\"\n", samName, name1, saiName, fastqFile);
+		bw.write(cmdTemp);
+		bw.close();
+
+		Thread.sleep(500);
+
+		String cmd[] = {"gnome-terminal", "-x", "bash", "-c", 
+				"echo 'Please wait till the SAM file gets created';"
+						+ "sh \"" + shellScript.getAbsolutePath() + "\";"
+						+ "echo 'Press Any Key To Continue...';"
+						+ "read"};
+
+		Path currentRelativePath = Paths.get("");
+		String location = currentRelativePath.toAbsolutePath()
+				.toString();
+		File dir = new File(location);
+		Process child = Runtime.getRuntime().exec(cmd, null, dir);
+		child.waitFor();
+
+		/*shellScript.delete();
+
+		File toDelete = new File(projectInfo.getPath() + PrepareFiles.prepareFileName(fastqFile, ".amb"));
+		toDelete.delete();
+
+		toDelete = new File(projectInfo.getPath() + PrepareFiles.prepareFileName(fastqFile, ".ann"));
+		toDelete.delete();
+
+		toDelete = new File(projectInfo.getPath() + PrepareFiles.prepareFileName(fastqFile, ".bwt"));
+		toDelete.delete();
+
+		toDelete = new File(projectInfo.getPath() + PrepareFiles.prepareFileName(fastqFile, ".pac"));
+		toDelete.delete();
+
+		toDelete = new File(projectInfo.getPath() + PrepareFiles.prepareFileName(fastqFile, ".sa"));
+		toDelete.delete();
+
+		toDelete = new File(projectInfo.getPath() + PrepareFiles.prepareFileName(fastqFile, ".sai"));
+		toDelete.delete();*/
+	}
+
+	private void setSequenceLengthText(int num){
+		String output = "" + num;
+		int counter = 0;
+		for (int index = output.length() - 1; index > 0; index--){
+			counter++;
+			if (counter % 3 == 0){
+				counter = 0;
+				output = output.substring(0,index) + "," + output.substring(index);
+			}
+		}
+
+		sequenceLengthLbl.setText(output);
+	}
+
+	private void remoteInstallHelp() {
+		RemoteInstall remote = new RemoteInstall();
+		remote.setParentFrame(this);
+		remote.setVisible(true);
+	}
+
+	private void clearTheForm(){
+		/*File tempFile = null;
+		if (samFilePathTxt.getText() != null && samFilePathTxt.getText().compareTo("") != 0){
+			tempFile = new File(samFilePathTxt.getText());
+		}
+
+		if(tempFile != null && tempFile.exists()){
+			tempFile = new File(PrepareFiles.prepareOutputFilePath(samFilePathTxt.getText(), projectInfo.getPath(), ".inspo"));
+			if(tempFile.exists()){
+				tempFile.delete();
+			}
+
+			tempFile = new File(PrepareFiles.prepareOutputFilePath(samFilePathTxt.getText(), projectInfo.getPath(), ".inspos"));
+			if(tempFile.exists()){
+				tempFile.delete();
+			}
+
+			tempFile = new File(PrepareFiles.prepareOutputFilePath(samFilePathTxt.getText(), projectInfo.getPath(), ".inspou"));
+			if(tempFile.exists()){
+				tempFile.delete();
+			}
+
+			tempFile = new File(PrepareFiles.prepareOutputFilePath(samFilePathTxt.getText(), projectInfo.getPath(), ".inspous"));
+			if(tempFile.exists()){
+				tempFile.delete();
+			}
+		}
+		 */
+		setToDefaultState();
+	}
+
+	private void anotherPlot(){
+		plotWaitLbl.setVisible(true);
+
+		final String title = String.format("Library Name: %s, Distribution of reads per unique insertion", (String) plotLibraryCombo.getSelectedItem());
+
+		(new Thread(new Runnable() {
+
+			@Override
+			public void run() {
+				try {	
+					ChartPanel panel = new ChartPanel(PlotData.anotherPlot((String) plotLibraryCombo.getSelectedItem(), title, projectInfo, countOnlyUniqueRadio.isSelected()));
+
+					PlotViewer frame = new PlotViewer();					
+					frame.setPlotName(title);
+					frame.setVisible(true);
+					frame.addPlot(panel);
+
+					plotWaitLbl.setVisible(false);
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		})).start();
+	}
+
+	private void plotDataMethod(){
+
+		if(winLenTxt.getText() == null || winLenTxt.getText().compareTo("") == 0){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please provide the window length", "Warning", JOptionPane.WARNING_MESSAGE);
+			return;
+		}
+		if(winStepTxt.getText() == null || winStepTxt.getText().compareTo("") == 0){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please provide the window step length", "Warning", JOptionPane.WARNING_MESSAGE);
+			return;
+		}
+
+		int len = 0;
+		int step = 0;
+
+		try{
+			len = Integer.parseInt(winLenTxt.getText());
+			step = Integer.parseInt(winStepTxt.getText());
+			plotWaitLbl.setVisible(true);
+			int tempLen = 0;
+			int tempStep = 0;
+
+			File winInfo = new File(projectInfo.getPath() + (String)plotLibraryCombo.getSelectedItem() + ".data");
+			if (winInfo.exists()){
+				BufferedReader br = new BufferedReader(new FileReader(winInfo));
+				String line = br.readLine();
+				tempLen = Integer.parseInt(line.substring(line.indexOf("=") + 2, line.length()));
+				line = br.readLine();
+				tempStep = Integer.parseInt(line.substring(line.indexOf("=") + 2, line.length()));
+				br.close();
+
+				if (tempLen != len || tempStep != step){
+					int result = JOptionPane.showConfirmDialog(this, "Window length and window step differes from the applied values. \nDo you want to apply the new values?");
+
+					if (result == JOptionPane.YES_OPTION){
+						setWinInfoAndSave(len, step);
+					}else if (result == JOptionPane.NO_OPTION){
+
+					}else{
+						return;
+					}
+				}
+			}
+		}catch (IOException e){
+			logger.fatal(e.getMessage());
+		}catch (NumberFormatException e1) {
+			JOptionPane.showMessageDialog(MainFrame.this, "Please enter a valid window length and step value.");
+			return;
+		}
+
+		final String title;
+		if (countOnlyUniqueRadio.isSelected()){
+			String temp = String.format("Library Name: %s (Counting unique insertions) | Window Length: %d | Window Steps: %d", (String) plotLibraryCombo.getSelectedItem(),
+					len, step);
+			title = temp;
+		} else{
+			String temp = String.format("Library Name: %s (Counting all reads) | Window Length: %d | Window Steps: %d", (String) plotLibraryCombo.getSelectedItem(),
+					len, step);
+			title = temp;
+		}
+
+		final int threadLen = len;
+		final int threadStep = step;
+		(new Thread(new Runnable() {
+			@Override
+			public void run() {
+				try {	
+					ChartPanel panel = new ChartPanel(PlotData.plotData((String) plotLibraryCombo.getSelectedItem(), threadLen, threadStep, title, projectInfo, countOnlyUniqueRadio.isSelected()));
+
+					PlotViewer frame = new PlotViewer();					
+					frame.setPlotName(title);
+					frame.setVisible(true);
+					frame.addPlot(panel);
+
+					plotWaitLbl.setVisible(false);
+				} catch (Exception e) {
+					e.printStackTrace();
+				}
+			}
+		})).start();
+
+	}
+
+	private void applySequenceNumber(){
+		String seqLen = sequenceLenTxt.getText();
+		if (seqLen == null || seqLen.compareTo("") == 0){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please Enter Your Sequence Number First!");
+			return;
+		}
+
+		int seqLenInt;
+		try{
+			seqLenInt = Integer.parseInt(seqLen);
+		}catch(NumberFormatException e){
+			JOptionPane.showMessageDialog(MainFrame.this, "Please enter a valid integer number.");
+			return;
+		}
+
+		if (MainFrame.this.hasSeqNum){
+			BufferedReader br = null;
+			BufferedWriter bw = null;
+			File temp = null;
+			try{
+				temp = new File("temp");
+				br = new BufferedReader(new FileReader(projectInfo.getFile()));
+				bw = new BufferedWriter(new FileWriter(temp));
+
+				String line = br.readLine();
+
+				while(line != null){
+
+					if(!line.contains(Messages.projectSequenceLen)){
+						bw.write(line + "\n");
+					}else{
+						bw.write(Messages.projectSequenceLen + seqLenInt + "\n");
+						projectInfo.setSequenceLen(seqLenInt);
+					}
+
+					line = br.readLine();
+				}
+
+				br.close();
+				bw.close();
+
+				projectInfo.getFile().delete();
+				temp.renameTo(projectInfo.getFile());
+
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return;
+			}finally{
+				try{
+					if (bw != null){
+						bw.close();
+					}
+					if (br != null){
+						br.close();
+					}
+				}catch(IOException e){
+					logger.error(e.getMessage());
+					return;
+				}
+			}
+		}else{
+			BufferedWriter bw = null;
+			try{
+				bw = new BufferedWriter(new FileWriter(projectInfo.getFile(), true));
+				bw.append(Messages.projectSequenceLen + seqLen + "\n");
+				projectInfo.setSequenceLen(seqLenInt);
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return;
+			}finally{
+				try{
+					if(bw != null){
+						bw.close();
+					}
+				}catch(IOException e){
+					logger.error(e.getMessage());
+					return;
+				}
+			}
+		}
+
+		hasSeqNum = true;
+		JOptionPane.showMessageDialog(MainFrame.this, "New sequence length has been applied!");
+		setSequenceLengthText(Integer.parseInt(seqLen));
+
+		if (hasGeneFile){
+			for (int i = 1; i < tabbedPane.getTabCount(); i++){
+				tabbedPane.setEnabledAt(i, true);
+			}
+			infoLbl.setVisible(false);
+		}
+	}
+
+	private void prepareGeneFile(){
+		if(imgRadioBtn.isSelected()){
+			int choice = JOptionPane.YES_OPTION;
+			if(hasGeneFile){
+				choice = JOptionPane.showConfirmDialog(MainFrame.this, "Do you want to replace the existing Gene File?", "Gene file already exists", JOptionPane.YES_NO_OPTION);
+			}
+
+			if(choice == JOptionPane.YES_OPTION){
+				if (imgFileTxt.getText() == null || imgFileTxt.getText().compareTo("") == 0){
+					JOptionPane.showMessageDialog(MainFrame.this, "Please select your IMG file.", "No IMG File", JOptionPane.WARNING_MESSAGE);
+					return;
+				}else if (scaffoldCombo.getSelectedItem() == null || ((String)scaffoldCombo.getSelectedItem()).compareTo("") == 0){
+					JOptionPane.showMessageDialog(MainFrame.this, "No scaffold selected to process.", "No Scaffold", JOptionPane.WARNING_MESSAGE);
+					return;
+				}
+
+				try {
+					PrepareFiles.processSelectedScaffold(imgFileTxt.getText(), (String) scaffoldCombo.getSelectedItem(), projectInfo);
+
+					if (projectInfo.getGeneFile() != null){
+						JOptionPane.showMessageDialog(MainFrame.this, "Genes file was created successfully.");
+						geneFileNameLbl.setText(scaffoldCombo.getSelectedItem() + ".genes");
+					}else{
+						geneFileNameLbl.setText("ERROR");
+						hasGeneFile = false;
+
+						for (int i = 1; i < tabbedPane.getTabCount(); i++){
+							tabbedPane.setEnabledAt(i, false);
+						}
+					}
+				} catch (IOException e) {
+					geneFileNameLbl.setText("ERROR");
+					logger.error(e.getMessage());
+					return;
+				}
+			}
+		}else{
+			String pttPath = pttFileTxt.getText();
+			if (pttPath != null && pttPath.compareTo("") != 0){
+
+				if (projectInfo.getSequenceLen() <= 0){
+					JOptionPane.showMessageDialog(this, "Please apply the sequence length first and try again");
+					return;
+				}
+
+				geneFileNameLbl.setText("Preparing...");
+
+				(new Thread(new Runnable(){
+					public void run() {
+						int choice = JOptionPane.YES_OPTION;
+						if(hasGeneFile){
+							choice = JOptionPane.showConfirmDialog(MainFrame.this, "Do you want to replace the existing Gene File?", "Gene file already exists", JOptionPane.YES_NO_OPTION);
+						}
+
+						if(choice == JOptionPane.YES_OPTION){
+							createGeneFile();
+
+							if (hasGeneFile){
+								geneFileNameLbl.setText(PrepareFiles.prepareFileName(projectInfo.getGeneFile().getAbsolutePath(), ""));
+								JOptionPane.showMessageDialog(MainFrame.this, "Genes File Created Successfully!");
+								PrepareFiles.deleteAllOtherGenesFiles(MainFrame.this.projectInfo.getGeneFile().getName(), MainFrame.this.projectInfo);
+
+								if (hasSeqNum){
+									for (int i = 1; i < tabbedPane.getTabCount(); i++){
+										tabbedPane.setEnabledAt(i, true);
+									}
+									infoLbl.setVisible(false);
+								}
+
+								if(projectInfo.getGeneFile() != null){
+									geneFileNameLbl.setText(projectInfo.getGeneFile().getName());
+								}else{
+									geneFileNameLbl.setText("Not Avail.");
+								}
+							}else{
+								JOptionPane.showMessageDialog(MainFrame.this, "There was an error in creating your Genes File.");
+								geneFileNameLbl.setText("ERROR");
+
+								for (int i = 1; i < tabbedPane.getTabCount(); i++){
+									tabbedPane.setEnabledAt(i, false);
+								}
+								hasGeneFile = false;
+							}
+						}else{
+							geneFileNameLbl.setText(projectInfo.getGeneFile().getName());
+						}
+					}
+				})).start();					
+			}else{
+				JOptionPane.showMessageDialog(MainFrame.this, "No PTT file was selected!", "No PTT File", JOptionPane.WARNING_MESSAGE);
+			}
+		}
+	}
+
+	@SuppressWarnings("resource")
+	private void replaceXlsFile(){
+
+		File xlsFile = new File(projectInfo.getPath() + dataTableCombo.getSelectedItem() + " - temp.table.xls"); //REPLACE
+		File tablefile = new File(projectInfo.getPath() + dataTableCombo.getSelectedItem() + ".table.xls"); //REPLACE
+
+		if(!xlsFile.exists()){
+			logger.fatal("The XLS file could not be found!!!");
+		}else{
+			if(xlsFile.canWrite()){
+				try{
+					FileChannel destination = new FileOutputStream(tablefile).getChannel();
+					FileChannel source = new FileInputStream(xlsFile).getChannel();
+					destination.transferFrom(source, 0, source.size());
+
+					source.close();
+					destination.close();
+
+					if(!xlsFile.delete()){
+						JOptionPane.showMessageDialog(MainFrame.this, "Please close the spreadsheet application.", "Could not write into the file", JOptionPane.ERROR_MESSAGE);
+						return;
+					}
+				}catch(IOException e){
+					logger.error(e.getMessage());
+					return;
+				}catch(NullPointerException e){
+					logger.error(e.getMessage());
+					return;
+				}
+			}else{
+				logger.fatal("The XLS file could not be written on!!!");
+				JOptionPane.showMessageDialog(MainFrame.this, "Please close the spreadsheet application.", "Could not write into the file", JOptionPane.ERROR_MESSAGE);
+				return;
+			}
+		}
+
+		BufferedWriter bw = null;
+		BufferedReader br = null;
+
+		xlsFile = new File("temp.table.xls"); //REPLACE
+
+		try{
+			bw = new BufferedWriter(new FileWriter(xlsFile));
+			br = new BufferedReader(new FileReader(tablefile));
+
+			String tempLine = br.readLine();
+			if (tempLine.startsWith("start_coord")){
+				bw.write("\t\t\t\t\t\t\t\n");
+				bw.write("\t\t\t\t\t\t\t\n");
+				bw.write("\t\t\t\t\t\t\t\n");
+				bw.write("\t\t\t\t\t\t\t\n");
+			}
+
+			//bw.write("\n");
+			//bw.write("\n");
+			//bw.write("\n");
+			//bw.write("\n");
+
+			br.close();
+			br = new BufferedReader(new FileReader(tablefile));
+			tempLine = br.readLine();
+			while(tempLine != null){
+				bw.write(tempLine + "\n");
+				tempLine = br.readLine();
+			}
+
+			bw.close();
+			br.close();
+
+			if(tablefile.delete()){
+				if(xlsFile.renameTo(tablefile)){
+					JOptionPane.showMessageDialog(MainFrame.this, "Replaced Successfully!");
+				}
+			}
+
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return;
+		}finally{
+			try{
+				bw.close();
+				br.close();				
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return;
+			}
+		}
+
+		for (int i = 0; i < tabbedPane.getTabCount(); i++){
+			tabbedPane.setEnabledAt(i, true);
+		}
+		infoLbl.setVisible(false);
+
+		addNewDataTableBtn.setEnabled(true);
+		openAsSpreadsheetBtn.setEnabled(true);
+		dataTableRemoveBtn.setEnabled(true);
+		dataTableRenameBtn.setEnabled(true);
+		addNewIndicesBtn.setEnabled(true);
+		dataTableCombo.setEnabled(true);
+		replaceXlsBtn.setEnabled(false);
+		tableCancelChangeBtn.setEnabled(false);
+	}
+
+	@SuppressWarnings("resource")
+	private void prepareXlsFileAndOpen() throws IOException{
+
+		String selectedItem = (String)dataTableCombo.getSelectedItem();
+
+		String warningMsg = String.format("You can make changes to the table such as manually add or remove genes (lines), change gene coordinates, or remove\n"
+				+ "previously added data columns, as long as the overall format is maintained. If you make changes to the table save it ...");
+
+		JOptionPane.showMessageDialog(MainFrame.this, warningMsg, "Warning", JOptionPane.WARNING_MESSAGE);
+
+		File selectedFile = new File(projectInfo.getPath() + selectedItem + ".table.xls"); //REPLACE
+		File xlsFile = new File(projectInfo.getPath() + selectedItem + " - temp.table.xls"); //REPLACE
+
+		FileChannel destination = new FileOutputStream(xlsFile).getChannel();
+		FileChannel source = new FileInputStream(selectedFile).getChannel();
+
+		if(destination != null && source != null){
+			destination.transferFrom(source, 0, source.size());
+		}
+
+		if(destination != null){
+			destination.close();
+		}
+
+		if(source != null){
+			source.close();
+		}
+
+		Desktop.getDesktop().open(xlsFile);
+
+		for (int i = 0; i < tabbedPane.getTabCount(); i++){
+			tabbedPane.setEnabledAt(i, false);
+		}
+
+		addNewDataTableBtn.setEnabled(false);
+		openAsSpreadsheetBtn.setEnabled(false);
+		dataTableRemoveBtn.setEnabled(false);
+		dataTableRenameBtn.setEnabled(false);
+		dataTableCombo.setEnabled(false);
+		addNewIndicesBtn.setEnabled(false);
+		replaceXlsBtn.setEnabled(true);
+		tableCancelChangeBtn.setEnabled(true);
+
+	}
+
+	private void initializeBWAPanel(){
+		String OSName = System.getProperty("os.name");
+
+		if(OSName.contains("Windows") || OSName.contains("windows")){
+			for (Component c : ((JPanel)tabbedPane.getSelectedComponent()).getComponents()){
+				c.setEnabled(false);
+			}
+
+			remoteHelpBtn.setEnabled(true);
+
+			JOptionPane.showMessageDialog(null, "Full functionality of this tab is only available when you are using Linux!!!\n"
+					+ "You can still use the 'Create SAM file manually' button to guide you through installing and running BWA on a remote Linux server.\n"
+					+ "\nYou will need:\n"
+					+ "  (i) an user account on a remote Linux server\n"
+					+ "  (ii) SSH and SFTP client installed on your computer");
+
+		}else{
+			bwaInstallBtn.setEnabled(false);
+			alreadyInstalledRadio.setSelected(true);
+
+			//Search for FNA
+			File folder = new File(projectInfo.getPath());
+			File[] listOfFiles = folder.listFiles();
+
+			for (int i = 0; i < listOfFiles.length; i++) {
+				if (listOfFiles[i].isFile() && listOfFiles[i].getName().endsWith(".fna")) {
+					fnaFilePath.setText(listOfFiles[i].getAbsolutePath());
+					break;
+				}
+			}
+		}
+	}
+
+	private void initializeBowtiePanel(){
+		//Search for FNA
+		File folder = new File(projectInfo.getPath());
+		File[] listOfFiles = folder.listFiles();
+
+		for (int i = 0; i < listOfFiles.length; i++) {
+			if (listOfFiles[i].isFile() && listOfFiles[i].getName().endsWith(".fna")) {
+				bowtieFnaTxt.setText(listOfFiles[i].getAbsolutePath());
+				break;
+			}
+		}
+
+		try{
+			if (bowtieSamLocTxt.getText() == null || bowtieSamLocTxt.getText().equals("")){
+				folder = new File(projectInfo.getPath());
+				listOfFiles = folder.listFiles();
+
+				String line = "";
+				for (int i = 0; i < listOfFiles.length; i++) {
+					if (listOfFiles[i].isFile() && listOfFiles[i].getName().endsWith("sam_loc")) {
+						BufferedReader br = new BufferedReader(new FileReader(listOfFiles[i]));
+						line = br.readLine();
+						br.close();
+					} 
+				}
+
+				if (!line.equals("")){
+					bowtieSamLocTxt.setText(line);
+				}else{
+					bowtieSamLocTxt.setText(projectInfo.getPath());
+				}
+			}
+		}catch(IOException e){
+			e.printStackTrace();
+		}
+	}
+
+	private void initiatePlotLibraryComboBox(){
+
+		BufferedReader br = null;
+
+		if(plotLibraryCombo != null){
+			plotLibraryCombo.removeAllItems();
+		}
+
+		try{
+			br = new BufferedReader(new FileReader(projectInfo.getFile()));
+
+			String line = br.readLine();
+			br.readLine();
+			br.readLine();
+
+			while(line != null){
+				line = br.readLine();
+
+				if (line != null)
+					plotLibraryCombo.addItem(line.substring(0, line.length() - 6));
+
+				line = br.readLine();
+				line = br.readLine();
+				line = br.readLine();
+			}
+
+			if (plotLibraryCombo.getItemCount() == 0){
+				plotBtn.setEnabled(false);
+				maxNumInsBtn.setEnabled(false);
+				maxNumInsTxt.setEnabled(false);
+				winLenTxt.setEnabled(false);
+				winStepTxt.setEnabled(false);
+			}else{
+				plotBtn.setEnabled(true);
+				maxNumInsBtn.setEnabled(true);
+				maxNumInsTxt.setEnabled(true);
+				winLenTxt.setEnabled(true);
+				winStepTxt.setEnabled(true);
+			}
+
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return;
+		}finally{
+			try{
+				br.close();
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return;
+			}
+		}		
+	}
+
+	private void initiateDataTablesComboBox(){
+
+		File projectDir = new File(projectInfo.getPath());
+		File[] tableFiles = projectDir.listFiles(new FilenameFilter() {
+
+			@Override
+			public boolean accept(File dir, String name) {
+				return (name.endsWith(".table.xls") || name.endsWith(".TABLE.XLS")); //REPLACE
+			}
+		});
+
+		if (tableFiles != null && tableFiles.length != 0){
+			dataTableRenameBtn.setEnabled(true);
+			dataTableRemoveBtn.setEnabled(true);
+			dataTableCombo.setEnabled(true);
+			openAsSpreadsheetBtn.setEnabled(true);
+			addNewIndicesBtn.setEnabled(true);
+
+			dataTableCombo.removeAllItems();
+			for (File t : tableFiles){
+				dataTableCombo.addItem(t.getName().substring(0, t.getName().length() - 10));
+			}
+		}else{
+			dataTableCombo.removeAllItems();
+			dataTableCombo.setEnabled(false);
+			dataTableCombo.addItem("No existing data table.");
+			dataTableRenameBtn.setEnabled(false);
+			addNewIndicesBtn.setEnabled(false);
+			dataTableRemoveBtn.setEnabled(false);
+			openAsSpreadsheetBtn.setEnabled(false);
+		}
+
+	}
+
+	private boolean findGeneFile(){
+
+		File projectDir = new File(projectInfo.getPath());
+		File[] matched = projectDir.listFiles(new FilenameFilter(){
+
+			@Override
+			public boolean accept(File arg0, String name) {
+				return (name.endsWith(".genes") || name.endsWith(".Genes")); 
+			}
+
+		});
+
+		if (matched.length != 1){
+			return false;
+		}
+
+		projectInfo.setGeneFile(matched[0]);
+		geneFileNameLbl.setText(projectInfo.getGeneFile().getName());
+		return true;
+	}
+
+	private void createGeneFile(){
+		String pttPath = pttFileTxt.getText();
+		String rntPath = rntFileTxt.getText();
+
+		String geneFilePath = PrepareFiles.createGeneFile(pttPath, rntPath, projectInfo.getPath(), projectInfo); 
+		if(geneFilePath.compareTo(Messages.failMsg) != 0){
+			hasGeneFile = true;
+			projectInfo.setGeneFile(new File(geneFilePath));
+		}else{
+			hasGeneFile = false;
+		}
+
+	}
+
+	private void initiateLibraryComboBox(){
+
+		BufferedReader br = null;
+
+		plotWaitLbl.setVisible(false);
+
+		if(libraryComboBox != null){
+			libraryComboBox.removeAllItems();
+		}
+
+		try{
+			br = new BufferedReader(new FileReader(projectInfo.getFile()));
+
+			String line = br.readLine();
+			br.readLine();
+			br.readLine();
+
+			while(line != null){
+				line = br.readLine();
+
+				if (line != null)
+					libraryComboBox.addItem(line.substring(0, line.length() - 6));
+
+				line = br.readLine();
+				line = br.readLine();
+				line = br.readLine();
+			}
+
+			br.close();
+
+			if (libraryComboBox.getItemCount() == 0){
+				renameLibBtn.setEnabled(false);
+				removeLibBtn.setEnabled(false);
+				btnOptimal.setEnabled(false);
+			}else{
+				renameLibBtn.setEnabled(true);
+				removeLibBtn.setEnabled(true);
+				btnOptimal.setEnabled(true);
+			}
+
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return;
+		}finally{
+			try{
+				br.close();
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return;
+			}
+		}
+
+		initiatePlotLibraryComboBox();
+
+		reloadWinInfo();
+
+		//GUI Difference in Linux and Windows Should be checked again!
+		String OSName = System.getProperty("os.name");
+		if(!(OSName.contains("Windows") || OSName.contains("windows"))){
+			if (if_initialize_step_1){
+				lblRemoveUniqueInsertions.setBounds(450, 214, 336, 14);
+				lblWindowLength.setBounds((int) lblWindowLength.getBounds().getX() - 20, (int) lblWindowLength.getBounds().getY(), (int) lblWindowLength.getBounds().getWidth(), (int) lblWindowLength.getBounds().getHeight());
+
+				lblReads.setBounds((int) lblReads.getBounds().getX() - 20, (int) lblReads.getBounds().getY() + 20, (int) lblReads.getBounds().getWidth(), (int) lblReads.getBounds().getHeight());
+				removeUniqueInsertionsTxt.setBounds((int) removeUniqueInsertionsTxt.getBounds().getX() - 20, (int) removeUniqueInsertionsTxt.getBounds().getY() + 20, 
+						(int) removeUniqueInsertionsTxt.getBounds().getWidth(), (int) removeUniqueInsertionsTxt.getBounds().getHeight());
+				label_10.setBounds((int) label_10.getBounds().getX(), (int) label_10.getBounds().getY() + 20, (int) label_10.getBounds().getWidth(), (int) label_10.getBounds().getHeight());
+
+				btnAnotherPlot.setSize(btnAnotherPlot.getWidth() + 60, btnAnotherPlot.getHeight());
+				btnAnotherPlot.setText(btnAnotherPlot.getText().replace("unique ", ""));
+				btnAnotherPlot.setBounds((int) btnAnotherPlot.getBounds().getX() - 80, (int) btnAnotherPlot.getBounds().getY(), (int) btnAnotherPlot.getBounds().getWidth(), (int) btnAnotherPlot.getBounds().getHeight());
+
+				if_initialize_step_1 = false;
+			}
+		}	
+
+	}
+
+	private void reloadWinInfo(){
+
+		try{
+			File winInfo = new File(projectInfo.getPath() + (String)plotLibraryCombo.getSelectedItem() + ".data");
+			if (winInfo.exists()){
+				BufferedReader br = new BufferedReader(new FileReader(winInfo));
+				String line = br.readLine();
+				winLenTxt.setText(line.substring(line.indexOf("=") + 2, line.length()));
+				line = br.readLine();
+				winStepTxt.setText(line.substring(line.indexOf("=") + 2, line.length()));
+				br.close();
+			}else{
+				winLenTxt.setText("");
+				winStepTxt.setText("");
+			}
+		}catch (IOException e){
+			logger.fatal(e.getMessage());
+		}
+
+	}
+
+	private void reloadProjectFromFile(){
+		String pathTemp = projectInfo.getPath() + "project.pro";
+		projectInfo.createFile(pathTemp);
+		if(!projectInfo.getFile().exists()){
+			JOptionPane.showMessageDialog(MainFrame.this, "There was an error finding your project file!"
+					+ "\nIt may be deleted."
+					+ "\n\nRerun the application and try other projects...");
+			logger.fatal("System has to be exited, because the project file was not found!!!");
+			System.exit(-1);
+		}
+
+		BufferedReader br = null;
+		try{
+			br = new BufferedReader(new FileReader(projectInfo.getFile()));
+			String line = br.readLine();
+			projectInfo.setName(line.substring(Messages.projectName.length()));
+
+			setTitle(ProgTitle + " " + ProgVersion);
+
+			line = br.readLine();
+			//projectInfo.setPath(pathTemp);
+
+			line = br.readLine();
+			if (line == null){
+				hasSeqNum = false;
+				return;
+			}else{
+				hasSeqNum = true;
+			}
+
+			projectInfo.setSequenceLen(Integer.parseInt(line.substring(Messages.projectSequenceLen.length())));
+			MainFrame.this.sequenceLenTxt.setText(projectInfo.getSequenceLen() + "");
+			setSequenceLengthText(projectInfo.getSequenceLen());
+
+			line = br.readLine();
+			int libCount = 0;
+			while(line != null){
+				line = br.readLine();
+				line = br.readLine();
+				line = br.readLine();
+				line = br.readLine();
+
+				libCount++;
+			}
+
+			libraryCountLbl.setText(libCount + "");
+
+			File projectDir = new File(projectInfo.getPath());
+			File[] matches = projectDir.listFiles(new FilenameFilter() {
+				public boolean accept(File arg0, String arg1) {
+					return (arg1.endsWith(".table.xls")); //REPLACE
+				}
+			});
+			dataTableCountLbl.setText(matches.length + "");
+
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return;
+		}finally{
+			try{
+				br.close();
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return;
+			}
+		}
+
+	}
+
+	private void setToDefaultState(){
+		samFilePathTxt.setText("");
+		browseForSamBtn.setEnabled(true);
+
+		extractInsBtn.setEnabled(false);
+		extractInsBtn.setText("Extract");
+
+		extractInsLbl.setForeground(Color.gray);
+		sortInsLbl.setForeground(Color.gray);
+		countUniLbl.setForeground(Color.gray);
+		sortUniLbl.setForeground(Color.gray);
+
+		doneLbl1.setVisible(false);
+		doneLbl2.setVisible(false);
+		doneLbl3.setVisible(false);
+		doneLbl4.setVisible(false);
+		loadingLbl.setVisible(false);
+	}
+
+	// 1
+	private class ExtractInsertions implements Runnable{
+		private int uniqueInsertionsLimit;
+		public ExtractInsertions(int uniqueInsertionsLimit) {
+			this.uniqueInsertionsLimit = uniqueInsertionsLimit;
+		}
+
+		@Override
+		public void run() {
+			String result = PrepareFiles.findTheLocationsInTheSamFile(MainFrame.this.samFilePathTxt.getText(), 
+					projectInfo.getPath(),
+					projectInfo.getSequenceLen());
+			if(result.compareTo(Messages.successMsg) == 0){
+				MainFrame.this.extractInsLbl.setForeground(Color.black);
+				MainFrame.this.sortInsLbl.setForeground(Color.BLUE);
+
+				doneLbl1.setVisible(true);
+				loadingLbl.setBounds(22, 239, 30, 16);
+
+				SortInsertions run = new SortInsertions(uniqueInsertionsLimit);
+				Thread runThread = new Thread(run);
+				runThread.start();
+			}else{
+				JOptionPane.showMessageDialog(MainFrame.this, "There was some error with extracting insertions from your file.");
+			}
+		}
+	}
+
+	// Step 2 - Creating Inspos File
+	private class SortInsertions implements Runnable{
+
+		private int uniqueInsertionsLimit;
+		public SortInsertions(int uniqueInsertionsLimit) {
+			this.uniqueInsertionsLimit = uniqueInsertionsLimit;
+		}
+
+		@Override
+		public void run() {
+			String result = PrepareFiles.sortTheLocationsFile(MainFrame.this.samFilePathTxt.getText(), projectInfo.getPath());
+			if(result.compareTo(Messages.successMsg) == 0){
+				String tailLine = MyFileUtil.tail(new File(PrepareFiles.prepareOutputFilePath(MainFrame.this.samFilePathTxt.getText(), projectInfo.getPath(), ".inspos")));
+
+				if (Integer.parseInt(tailLine) > projectInfo.getSequenceLen()){
+					File inspos = new File(PrepareFiles.prepareOutputFilePath(MainFrame.this.samFilePathTxt.getText(), projectInfo.getPath(), ".inspos"));
+					File inspo = new File(PrepareFiles.prepareOutputFilePath(MainFrame.this.samFilePathTxt.getText(), projectInfo.getPath(), ".inspo"));
+
+					if(inspo.delete()){
+						if(inspos.delete()){
+							JOptionPane.showMessageDialog(MainFrame.this, ""
+									+ "ERROR: insertions were found at positions above the provided sequence length. The library\n"
+									+ "was not created.\n"
+									+ "\n"
+									+ "Possible reasons and solutions:\n"
+									+ "- The sequence length is incorrect. Verify the sequence length and if necessary correct it in the\n"
+									+ "'Main' tab.\n"
+									+ "- You have used a wrong DNA sequence when running the Burrows-WheelerAligner to locate\n"
+									+ "the insertions and generate the .sam file. Run BWA with the correct sequence.\n"
+									+ "- Some of the input files are not formatted properly. Verify that all input files, including the\n\n"
+									+ "DNA sequence used for BWA, have the correct format."
+									+ "This error can also occur if you did not push 'apply' to enter the sequence length prior to continuing", "ERROR", JOptionPane.ERROR_MESSAGE);
+
+							clearTheForm();
+							return;
+						}
+					}
+
+					return;
+				}
+
+				MainFrame.this.sortInsLbl.setForeground(Color.black);
+				MainFrame.this.countUniLbl.setForeground(Color.BLUE);
+
+				doneLbl2.setVisible(true);
+				loadingLbl.setBounds(22, 258, 30, 16);
+
+				CountUnique run = new CountUnique(uniqueInsertionsLimit);
+				Thread runThread = new Thread(run);
+				runThread.start();
+			}else{
+				JOptionPane.showMessageDialog(MainFrame.this, "There was some error with sorting extracted insertions in your file.");
+			}
+		}
+	}
+
+	// Step 3 - Create InspoU File
+	private class CountUnique implements Runnable{
+
+		private int uniqueInsertionsLimit;
+
+		public CountUnique(int uniqueInsertionsLimit){
+			this.uniqueInsertionsLimit = uniqueInsertionsLimit;
+		}
+
+		@Override
+		public void run() {
+			String result = PrepareFiles.countUniqueLocations(MainFrame.this.samFilePathTxt.getText(), projectInfo.getPath(), uniqueInsertionsLimit);
+			if(result.compareTo(Messages.successMsg) == 0){
+
+				MainFrame.this.sortUniLbl.setForeground(Color.BLUE);
+				MainFrame.this.countUniLbl.setForeground(Color.black);
+
+				doneLbl3.setVisible(true);
+				loadingLbl.setBounds(22, 277, 30, 16);
+
+				SortByNumberOfInsertions run = new SortByNumberOfInsertions();
+				Thread runThread = new Thread(run);
+				runThread.start();
+			}else{
+				JOptionPane.showMessageDialog(MainFrame.this, "There was some error with sorting extracted insertions in your file.");
+			}
+		}
+	}
+
+
+	// Step 4 - Creating InspoUs File
+	private class SortByNumberOfInsertions implements Runnable{
+		@Override
+		public void run() {
+			String result = PrepareFiles.countUniqueLocationsSortedByNumbers(MainFrame.this.samFilePathTxt.getText(), projectInfo.getPath());
+			if(result.compareTo(Messages.successMsg) == 0){
+				MainFrame.this.sortUniLbl.setForeground(Color.black);
+				MainFrame.this.browseForSamBtn.setEnabled(false);	
+				BufferedWriter bw = null;
+
+				try{
+					bw = new BufferedWriter(new FileWriter(projectInfo.getFile(), true));
+
+					File folder = new File(projectInfo.getPath());
+					File[] listOfFiles = folder.listFiles();
+
+					boolean useTemp = false;
+					for (int i = 0; i < listOfFiles.length; i++) {
+						if (listOfFiles[i].isFile() && listOfFiles[i].getName().endsWith(".inspo")) {
+							if (listOfFiles[i].getAbsolutePath().contains("-temp.inspo")){
+								useTemp = true;
+							}
+						}
+					}
+
+					if (useTemp){
+						bw.write(PrepareFiles.prepareFileName(samFilePathTxt.getText(), "-temp.inspo") + "\n");
+						bw.write(PrepareFiles.prepareFileName(samFilePathTxt.getText(), "-temp.inspos") + "\n");
+						bw.write(PrepareFiles.prepareFileName(samFilePathTxt.getText(), "-temp.inspou") + "\n");
+						bw.write(PrepareFiles.prepareFileName(samFilePathTxt.getText(), "-temp.inspous") + "\n");						
+					}else{
+						bw.write(PrepareFiles.prepareFileName(samFilePathTxt.getText(), ".inspo") + "\n");
+						bw.write(PrepareFiles.prepareFileName(samFilePathTxt.getText(), ".inspos") + "\n");
+						bw.write(PrepareFiles.prepareFileName(samFilePathTxt.getText(), ".inspou") + "\n");
+						bw.write(PrepareFiles.prepareFileName(samFilePathTxt.getText(), ".inspous") + "\n");
+					}
+
+					bw.close();
+
+					doneLbl4.setVisible(true);
+					loadingLbl.setVisible(false);
+
+					String libraryName = "";
+
+					if (useTemp){
+						libraryName = JOptionPane.showInputDialog(MainFrame.this, "Enter the library's name:", 
+								PrepareFiles.prepareFileName(samFilePathTxt.getText(), "-temp"));
+						String selectedLib = PrepareFiles.prepareFileName(samFilePathTxt.getText(), "-temp");
+
+						if (libraryName.endsWith("-temp")){
+							libraryName = PrepareFiles.prepareFileName(samFilePathTxt.getText(), "") + "-temp-" + (new Random().nextInt(1000));
+						}
+
+						renameLibrary(libraryName, selectedLib);
+
+					}else{
+						libraryName = JOptionPane.showInputDialog(MainFrame.this, "Enter the library's name:", 
+								PrepareFiles.prepareFileName(samFilePathTxt.getText(), ""));
+
+						renameLibrary(libraryName, PrepareFiles.prepareFileName(samFilePathTxt.getText(), ""));
+					}
+
+					JOptionPane.showMessageDialog(MainFrame.this, "Library added to the project.");
+					libraryCountLbl.setText((Integer.parseInt(libraryCountLbl.getText()) + 1) + "");
+
+				}catch(IOException e){
+					logger.error(e.getMessage());
+					return;
+				}finally{
+					try{
+						bw.close();
+						initiateLibraryComboBox();
+					}catch(IOException e){
+						logger.error(e.getMessage());
+						return;
+					}
+				}
+			}else{
+				JOptionPane.showMessageDialog(MainFrame.this, "There was some error with sorting extracted insertions in your file.");
+			}
+		}
+	}
+
+	public void changeWinLenTo(String txt){
+		winlenLbl.setText(txt);
+	}
+
+	public void makeWinlenLblVisible(boolean isVisible){
+		btnOptimal.setVisible(!isVisible);
+		winlenLbl.setVisible(isVisible);
+	}
+}
diff --git a/src/GUI/PlotViewer.java b/src/GUI/PlotViewer.java
new file mode 100644
index 0000000..4cb97e6
--- /dev/null
+++ b/src/GUI/PlotViewer.java
@@ -0,0 +1,210 @@
+package GUI;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.EtchedBorder;
+
+import org.jdesktop.swingx.JXLabel;
+import org.jfree.chart.ChartPanel;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.data.Range;
+
+import com.jgoodies.forms.layout.FormLayout;
+import com.jgoodies.forms.layout.ColumnSpec;
+import com.jgoodies.forms.factories.FormFactory;
+import com.jgoodies.forms.layout.RowSpec;
+import java.awt.Font;
+
+ at SuppressWarnings("serial")
+public class PlotViewer extends JFrame {
+
+	public JLabel plotInfo = new JXLabel("New label");
+	public boolean hasChartListener = false;
+	private JPanel contentPane;
+	private JPanel plotPanel = new JPanel();
+	private JTextField xStartTxt;
+	private JTextField xEndTxt;
+	private JTextField yStartTxt;
+	private JTextField yEndTxt;
+	private JPanel parametersPanel = new JPanel();
+	private JPanel panel = new JPanel();
+	
+	/**
+	 * Create the frame.
+	 */
+	public PlotViewer() {
+		setResizable(false);
+		setTitle("Plot");
+		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+		setBounds(100, 100, 769, 702);
+		contentPane = new JPanel();
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		setContentPane(contentPane);
+		contentPane.setLayout(null);
+		
+		plotPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
+		plotPanel.setBounds(10, 36, 743, 480);
+		contentPane.add(plotPanel);
+		
+		JLabel lblResultPlot = new JLabel("Result plot:");
+		lblResultPlot.setBounds(10, 11, 96, 14);
+		contentPane.add(lblResultPlot);
+		
+		parametersPanel.setBounds(10, 575, 743, 89);
+		contentPane.add(parametersPanel);
+		parametersPanel.setLayout(new FormLayout(new ColumnSpec[] {
+				ColumnSpec.decode("155px"),
+				FormFactory.RELATED_GAP_COLSPEC,
+				ColumnSpec.decode("max(47dlu;default)"),
+				ColumnSpec.decode("67px"),
+				FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
+				ColumnSpec.decode("59px"),
+				FormFactory.RELATED_GAP_COLSPEC,
+				ColumnSpec.decode("max(41dlu;default)"),
+				FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
+				ColumnSpec.decode("61px"),
+				FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
+				ColumnSpec.decode("23px"),
+				FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
+				ColumnSpec.decode("32px"),
+				FormFactory.LABEL_COMPONENT_GAP_COLSPEC,
+				ColumnSpec.decode("89px"),},
+			new RowSpec[] {
+				FormFactory.LINE_GAP_ROWSPEC,
+				RowSpec.decode("20px"),
+				FormFactory.RELATED_GAP_ROWSPEC,
+				FormFactory.DEFAULT_ROWSPEC,
+				FormFactory.LINE_GAP_ROWSPEC,
+				RowSpec.decode("23px"),}));
+		
+		JLabel lblChangePlotRanges = new JLabel("Change plot ranges:");
+		parametersPanel.add(lblChangePlotRanges, "1, 2, left, center");
+		
+		JLabel lblXAxisStart = new JLabel("X Axis start:");
+		parametersPanel.add(lblXAxisStart, "3, 4, left, center");
+		
+		xStartTxt = new JTextField();
+		parametersPanel.add(xStartTxt, "4, 4, left, top");
+		xStartTxt.setText("0.0");
+		xStartTxt.setColumns(10);
+		
+		JLabel lblXAxisEnd = new JLabel("X Axis end:");
+		parametersPanel.add(lblXAxisEnd, "8, 4, left, center");
+		
+		xEndTxt = new JTextField();
+		parametersPanel.add(xEndTxt, "10, 4, left, top");
+		xEndTxt.setText("2000.0");
+		xEndTxt.setColumns(10);
+		
+		JLabel lblYAxisStart = new JLabel("Y Axis start:");
+		parametersPanel.add(lblYAxisStart, "3, 6, left, center");
+		
+		yStartTxt = new JTextField();
+		parametersPanel.add(yStartTxt, "4, 6, left, top");
+		yStartTxt.setText("0.0");
+		yStartTxt.setColumns(10);
+		
+		JLabel lblYAxisEnd = new JLabel("Y Axis end:");
+		parametersPanel.add(lblYAxisEnd, "8, 6, left, center");
+		
+		yEndTxt = new JTextField();
+		parametersPanel.add(yEndTxt, "10, 6, right, center");
+		yEndTxt.setText("300.0");
+		yEndTxt.setColumns(10);
+		
+		JButton replotBtn = new JButton("Re-Plot");
+		parametersPanel.add(replotBtn, "16, 6, left, top");
+		
+		panel.setBounds(10, 527, 743, 37);
+		contentPane.add(panel);
+		panel.setLayout(new BorderLayout(0, 0));
+		plotInfo.setFont(new Font("Tahoma", Font.BOLD, 13));
+		plotInfo.setText("Hover Points in the chart to get some information about it if available.");
+		
+		panel.add(plotInfo, BorderLayout.CENTER);
+		((JXLabel)plotInfo).setLineWrap(true);
+		replotBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				replot();
+			}
+		});
+	}
+	
+	public void replot(){
+		
+		Double xStart = null;
+		
+		if (xStartTxt.getText() != null || xStartTxt.getText().compareTo("") != 0){
+			xStart = Double.parseDouble(xStartTxt.getText());
+		}
+		
+		Double xEnd = null;
+		
+		if (xEndTxt.getText() != null || xEndTxt.getText().compareTo("") != 0){
+			xEnd = Double.parseDouble(xEndTxt.getText());
+		}
+		
+		Double yStart = null;
+		
+		if (yStartTxt.getText() != null || yStartTxt.getText().compareTo("") != 0){
+			yStart = Double.parseDouble(yStartTxt.getText());
+		}
+		
+		Double yEnd = null;
+		
+		if (yEndTxt.getText() != null || yEndTxt.getText().compareTo("") != 0){
+			yEnd = Double.parseDouble(yEndTxt.getText());
+		}
+		
+		ChartPanel panel = (ChartPanel) plotPanel.getComponent(0);
+		JFreeChart chart = panel.getChart();
+		XYPlot plot = chart.getXYPlot();
+		
+		if (xStart != null && xEnd != null){
+			plot.getDomainAxis().setRange(xStart, xEnd);
+		}
+		
+		if (yStart != null && yEnd != null){
+			plot.getRangeAxis().setRange(yStart, yEnd);
+		}
+	}
+	
+	public void addPlot(ChartPanel chart){
+		plotPanel.setLayout(new BorderLayout());
+		plotPanel.add(chart, BorderLayout.CENTER);
+		plotPanel.validate();
+		
+		//Initializing the default values for ranges
+		JFreeChart chart1 = chart.getChart();
+		if (chart1.getPlot() instanceof XYPlot){
+			XYPlot plot = chart1.getXYPlot();
+			Range range = plot.getDomainAxis().getRange();
+			xStartTxt.setText(range.getLowerBound() + "");
+			xEndTxt.setText(range.getUpperBound() + "");
+			range = plot.getRangeAxis().getRange();
+			yStartTxt.setText(range.getLowerBound() + "");
+			yEndTxt.setText(range.getUpperBound() + "");
+		}else{
+			for (int i = 0; i < parametersPanel.getComponentCount(); i++){
+				parametersPanel.getComponent(i).setEnabled(false);
+			}
+		}
+		
+		if (!hasChartListener){
+			panel.setVisible(false);
+		}
+	}
+	
+	public void setPlotName(String title){
+		setTitle(title);
+	}
+}
diff --git a/src/GUI/ProgressBarUpdater.java b/src/GUI/ProgressBarUpdater.java
new file mode 100644
index 0000000..b3e7a44
--- /dev/null
+++ b/src/GUI/ProgressBarUpdater.java
@@ -0,0 +1,40 @@
+package GUI;
+
+import javax.swing.JProgressBar;
+
+public class ProgressBarUpdater implements Runnable {
+
+	JProgressBar bar = null;
+	int size = -1;
+	int current = 0;
+	
+	public ProgressBarUpdater(JProgressBar bar, int size){
+		this.size = size;
+		this.bar = bar;
+	}
+	
+	@Override
+	public void run() {
+		
+		while(true){
+			try {
+				Thread.sleep(500);
+			} catch (InterruptedException e) {
+				e.printStackTrace();
+			}
+			
+			int valueTemp = (int)((current * 100.0) / size);
+			bar.setValue(valueTemp);
+			
+			if (current == -1){
+				break;
+			}
+		}
+		
+	}
+	
+	public void setCurrent(int current){
+		this.current = current;
+	}
+
+}
diff --git a/src/GUI/RemoteInstall.java b/src/GUI/RemoteInstall.java
new file mode 100644
index 0000000..fcefa56
--- /dev/null
+++ b/src/GUI/RemoteInstall.java
@@ -0,0 +1,303 @@
+package GUI;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Desktop;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+
+import java.awt.Font;
+
+public class RemoteInstall extends JFrame {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	private JFrame parentFrame = null;
+	
+	private JPanel contentPane;
+	private JTextField txtTar;
+	private JTextField txtCdBwaa;
+	private JTextField txtMake;
+	private JTextField txtusrsbinalternativesinstallusrbinbwa;
+	private JTextField txtWgetFileurl;
+	private JTextField txtBwaIndexp;
+	private JTextField txtBwaAlnk;
+	private JTextField txtBwaSamsef;
+
+	/**
+	 * Create the frame.
+	 */
+	public RemoteInstall() {
+		setTitle("Create SAM file manually");
+		setResizable(false);
+		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+		setBounds(100, 100, 818, 577);
+		this.setLocationRelativeTo(parentFrame);
+		contentPane = new JPanel();
+		contentPane.setForeground(Color.BLACK);
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		setContentPane(contentPane);
+		contentPane.setLayout(null);
+		
+		JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
+		tabbedPane.setBounds(10, 11, 792, 526);
+		contentPane.add(tabbedPane);
+		
+		JPanel panel = new JPanel();
+		tabbedPane.addTab("Install BWA on your remote machine", null, panel, null);
+		panel.setLayout(null);
+		
+		JLabel lblDownloadBwa = new JLabel("2. Download BWA source code from  their website");
+		lblDownloadBwa.setBounds(20, 86, 680, 14);
+		panel.add(lblDownloadBwa);
+		
+		JLabel label_1 = new JLabel("BWA website");
+		setHandCursor(label_1);
+		label_1.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				openBrowserFor("http://sourceforge.net/projects/bio-bwa/files/");
+			}
+		});
+		label_1.setForeground(Color.BLUE);
+		label_1.setBounds(40, 111, 244, 14);
+		panel.add(label_1);
+		
+		JLabel label_2 = new JLabel("Steps to install BWA on your remote machine:");
+		label_2.setBounds(10, 11, 633, 14);
+		panel.add(label_2);
+		
+		JLabel lblConnectTo = new JLabel("1. Connect to your remote machine using SSH. ");
+		lblConnectTo.setBounds(20, 36, 690, 14);
+		panel.add(lblConnectTo);
+		
+		JLabel lblyouCanUse = new JLabel("You can use WinSCP as your SSH client");
+		setHandCursor(lblyouCanUse);
+		lblyouCanUse.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				openBrowserFor("http://http://winscp.net/eng/index.php");
+			}
+		});
+		lblyouCanUse.setForeground(Color.BLUE);
+		lblyouCanUse.setBounds(40, 61, 406, 14);
+		panel.add(lblyouCanUse);
+		
+		JLabel lblYouCan = new JLabel("- You can download the file using 'wget' command like this, ");
+		lblYouCan.setBounds(30, 139, 680, 14);
+		panel.add(lblYouCan);
+		
+		JLabel lblUncompressThe = new JLabel("3. Uncompress the downloaded file using the example command below:");
+		lblUncompressThe.setBounds(20, 195, 747, 14);
+		panel.add(lblUncompressThe);
+		
+		txtTar = new JTextField();
+		txtTar.setText("tar -jxf bwa-0.7.5a.tar.bz2");
+		txtTar.setEditable(false);
+		txtTar.setBounds(159, 220, 151, 20);
+		panel.add(txtTar);
+		txtTar.setColumns(10);
+		
+		JLabel lblExample = new JLabel("- Example:");
+		lblExample.setBounds(30, 223, 78, 14);
+		panel.add(lblExample);
+		
+		JLabel lblOpenThe = new JLabel("4. Open the uncompressed folder using the example below:");
+		lblOpenThe.setBounds(20, 248, 436, 14);
+		panel.add(lblOpenThe);
+		
+		JLabel label = new JLabel("- Example:");
+		label.setBounds(30, 276, 78, 14);
+		panel.add(label);
+		
+		txtCdBwaa = new JTextField();
+		txtCdBwaa.setText("cd bwa-0.7.5a");
+		txtCdBwaa.setEditable(false);
+		txtCdBwaa.setColumns(10);
+		txtCdBwaa.setBounds(159, 273, 151, 20);
+		panel.add(txtCdBwaa);
+		
+		JLabel lblCompileThe = new JLabel("5. Compile the code using the command below:");
+		lblCompileThe.setBounds(20, 301, 436, 14);
+		panel.add(lblCompileThe);
+		
+		JLabel label_3 = new JLabel("- Example:");
+		label_3.setBounds(30, 329, 78, 14);
+		panel.add(label_3);
+		
+		txtMake = new JTextField();
+		txtMake.setText("make");
+		txtMake.setEditable(false);
+		txtMake.setColumns(10);
+		txtMake.setBounds(159, 326, 151, 20);
+		panel.add(txtMake);
+		
+		JLabel lblInstallThe = new JLabel("6. Install the application using the example command below:");
+		lblInstallThe.setBounds(20, 354, 536, 14);
+		panel.add(lblInstallThe);
+		
+		JLabel label_4 = new JLabel("- Example:");
+		label_4.setBounds(30, 382, 78, 14);
+		panel.add(label_4);
+		
+		txtusrsbinalternativesinstallusrbinbwa = new JTextField();
+		txtusrsbinalternativesinstallusrbinbwa.setText("/usr/sbin/alternatives --install /usr/bin/bwa bwa (Uncompressed Directory) 20000");
+		txtusrsbinalternativesinstallusrbinbwa.setEditable(false);
+		txtusrsbinalternativesinstallusrbinbwa.setColumns(10);
+		txtusrsbinalternativesinstallusrbinbwa.setBounds(159, 379, 401, 20);
+		panel.add(txtusrsbinalternativesinstallusrbinbwa);
+		
+		JLabel lblInTheExample = new JLabel("- In the example command above, you only have to replace the (Uncompressed Directory)");
+		lblInTheExample.setBounds(30, 407, 737, 14);
+		panel.add(lblInTheExample);
+		
+		JLabel lblPathOfThe = new JLabel("with the complete path of the uncompressed folder");
+		lblPathOfThe.setBounds(40, 432, 466, 14);
+		panel.add(lblPathOfThe);
+		
+		JLabel lblBwaIs = new JLabel("7. BWA is installed");
+		lblBwaIs.setBounds(20, 457, 436, 14);
+		panel.add(lblBwaIs);
+		
+		txtWgetFileurl = new JTextField();
+		txtWgetFileurl.setEditable(false);
+		txtWgetFileurl.setText("wget FileURL");
+		txtWgetFileurl.setBounds(159, 164, 151, 20);
+		panel.add(txtWgetFileurl);
+		txtWgetFileurl.setColumns(10);
+		
+		JLabel label_5 = new JLabel("- Example:");
+		label_5.setBounds(40, 167, 78, 14);
+		panel.add(label_5);
+		
+		JPanel panel_1 = new JPanel();
+		tabbedPane.addTab("Run BWA on your remote machine", null, panel_1, null);
+		panel_1.setLayout(null);
+		
+		JLabel lblAfter = new JLabel("1. Make sure you have the BWA program installed");
+		lblAfter.setBounds(10, 11, 767, 14);
+		panel_1.add(lblAfter);
+		
+		JLabel lblTranferYour = new JLabel("2. Tranfer your files to the remote machine using SFTP. You will need a FNA file and a FASTQ file.");
+		lblTranferYour.setBounds(10, 36, 767, 14);
+		panel_1.add(lblTranferYour);
+		
+		JLabel lblYouCanUse = new JLabel("You can use WinSCP as your SSH client");
+		setHandCursor(lblYouCanUse);
+		lblYouCanUse.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				openBrowserFor("http://winscp.net/eng/index.php");
+			}
+		});
+		lblYouCanUse.setForeground(Color.BLUE);
+		lblYouCanUse.setBounds(20, 61, 406, 14);
+		panel_1.add(lblYouCanUse);
+		
+		JLabel lblAfterTransfering = new JLabel("3. After transferring the files to the remote machine, run the following command using SSH.");
+		lblAfterTransfering.setBounds(10, 86, 767, 14);
+		panel_1.add(lblAfterTransfering);
+		
+		JLabel lblChangeFileNames = new JLabel("Change between the parentheses:");
+		lblChangeFileNames.setBounds(20, 111, 566, 14);
+		panel_1.add(lblChangeFileNames);
+		
+		txtBwaIndexp = new JTextField();
+		txtBwaIndexp.setText("bwa index -p (Name1) (FNA file)");
+		txtBwaIndexp.setEditable(false);
+		txtBwaIndexp.setBounds(306, 108, 313, 20);
+		panel_1.add(txtBwaIndexp);
+		txtBwaIndexp.setColumns(10);
+		
+		JLabel lblAfterRunninng = new JLabel("4. After running the previous command, run the following command.");
+		lblAfterRunninng.setBounds(10, 136, 767, 14);
+		panel_1.add(lblAfterRunninng);
+		
+		JLabel label_6 = new JLabel("Change between the parentheses:");
+		label_6.setBounds(20, 164, 566, 14);
+		panel_1.add(label_6);
+		
+		txtBwaAlnk = new JTextField();
+		txtBwaAlnk.setText("bwa aln -k 2 -n 0.001 -l 18 (Name1) (FASTQ file) > (Name2).sai");
+		txtBwaAlnk.setEditable(false);
+		txtBwaAlnk.setColumns(10);
+		txtBwaAlnk.setBounds(306, 161, 313, 20);
+		panel_1.add(txtBwaAlnk);
+		
+		JLabel lbltheParametersk = new JLabel("* You can modify the parameters ... if you understand their meaning adn you believe that other values may be more appropriate.");
+		lbltheParametersk.setBounds(20, 189, 757, 14);
+		panel_1.add(lbltheParametersk);
+		
+		JLabel lblFinalStep = new JLabel("5. Final step to create a SAM file is to run the next command.");
+		lblFinalStep.setBounds(10, 214, 767, 14);
+		panel_1.add(lblFinalStep);
+		
+		JLabel label_7 = new JLabel("Change between the parentheses:");
+		label_7.setBounds(20, 242, 566, 14);
+		panel_1.add(label_7);
+		
+		txtBwaSamsef = new JTextField();
+		txtBwaSamsef.setText("bwa samse -f (Name3).sam (Name1) (Name2).sai (FASTQ file)");
+		txtBwaSamsef.setEditable(false);
+		txtBwaSamsef.setColumns(10);
+		txtBwaSamsef.setBounds(306, 239, 313, 20);
+		panel_1.add(txtBwaSamsef);
+		
+		JLabel lblYouCan_1 = new JLabel("6. Transfer the created SAM file back to your own machine.");
+		lblYouCan_1.setBounds(10, 267, 767, 14);
+		panel_1.add(lblYouCan_1);
+		
+		JLabel lblYouCan_2 = new JLabel("7. Use the created SAM file to add new libraries to the project in the \"Manage Libraries\" tab.");
+		lblYouCan_2.setBounds(10, 292, 767, 14);
+		panel_1.add(lblYouCan_2);
+		
+		JLabel label_8 = new JLabel("(?)");
+		label_8.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(RemoteInstall.this, "The FASTQ file contains your sequence reads and you should have received it from Illumina or the sequencing facility\n"
+						+ "you used. The FNA file contains the genomic DNA sequence in fastA format and you can download it for complete\n"
+						+ "prokaryotic genomes from the NCBI ftp server at ftp://ftp.ncbi.nih.gov/genomes/Bacteria/");
+			}
+		});
+		label_8.setToolTipText("Click me!");
+		label_8.setForeground(Color.BLUE);
+		label_8.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label_8.setBounds(561, 31, 88, 25);
+		panel_1.add(label_8);
+	}
+	
+	private void setHandCursor(Component a){
+		a.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+	}
+	
+	private void openBrowserFor(String url){
+		try {
+			Desktop.getDesktop().browse(new URI(url));
+		} catch (IOException e1) {
+			e1.printStackTrace();
+		} catch (URISyntaxException e1) {
+			e1.printStackTrace();
+		}
+	}
+	
+	public void setParentFrame(JFrame parent){
+		this.parentFrame = parent;
+		this.setLocationRelativeTo(parentFrame);
+	}
+}
diff --git a/src/GUI/SelectFNA.java b/src/GUI/SelectFNA.java
new file mode 100644
index 0000000..8576a64
--- /dev/null
+++ b/src/GUI/SelectFNA.java
@@ -0,0 +1,414 @@
+package GUI;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.JRadioButton;
+import javax.swing.JSeparator;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.io.CopyStreamAdapter;
+import org.apache.log4j.Logger;
+
+import essgenes.ProjectInfo;
+
+public class SelectFNA extends JFrame {
+
+	private Logger logger = Logger.getLogger(SelectFNA.class.getName());
+	private static final long serialVersionUID = 5257955296700178709L;
+	private final JPanel contentPanel = new JPanel();
+	private JTextField gbkPathTxt;
+	private JButton browseBtn = new JButton("Browse");
+	private JRadioButton downloadRdBtn = new JRadioButton("Download sequence file from NCBI server");
+	private JComboBox<String> firstLevelCombo = new JComboBox<String>();
+	private JComboBox<String> secondLevelCombo = new JComboBox<String>();
+	private JButton downloadBtn = new JButton("Download");
+	private JRadioButton previousRdBtn = new JRadioButton("Use previously downloaded file from NCBI");
+	private ProjectInfo info = null;
+	private Thread secondLevelThread = null;
+	private JProgressBar progressBar = new JProgressBar();
+	private JFrame parent = null;
+
+	/**
+	 * Create the dialog.
+	 */
+	public SelectFNA(ProjectInfo info, final JFrame parent, final JTextField textfield) {
+		setResizable(false);
+		this.info = info;
+		this.parent = parent;
+		setBounds(100, 100, 697, 281);
+		getContentPane().setLayout(new BorderLayout());
+		contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
+		getContentPane().add(contentPanel, BorderLayout.CENTER);
+		contentPanel.setLayout(null);
+		
+		JLabel label = new JLabel("(?)");
+		label.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				JOptionPane.showMessageDialog(SelectFNA.this, "DNA sequence in GenBank format");
+			}
+		});
+		label.setToolTipText("Click me!");
+		label.setForeground(Color.BLUE);
+		label.setFont(new Font("Tahoma", Font.PLAIN, 11));
+		label.setBounds(116, 12, 88, 14);
+		contentPanel.add(label);
+		
+		JLabel label_1 = new JLabel("Sequence file:");
+		label_1.setBounds(10, 11, 157, 14);
+		contentPanel.add(label_1);
+		previousRdBtn.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent arg0) {
+				previousRdBtn.setSelected(true);
+
+				firstLevelCombo.setEnabled(false);
+				secondLevelCombo.setEnabled(false);
+				downloadBtn.setEnabled(false);
+
+				gbkPathTxt.setEnabled(true);
+				browseBtn.setEnabled(true);
+			}
+		});
+
+		previousRdBtn.setBounds(20, 32, 352, 23);
+		contentPanel.add(previousRdBtn);
+		
+		gbkPathTxt = new JTextField();
+		gbkPathTxt.setEditable(false);
+		gbkPathTxt.setColumns(10);
+		gbkPathTxt.setBounds(30, 63, 508, 20);
+		contentPanel.add(gbkPathTxt);
+		browseBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath()
+						.toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+				fileChooser.setFileFilter(new FileNameExtensionFilter("FASTQ Files (.fna)", "fna"));
+				int result = fileChooser.showOpenDialog(parent);
+
+				if(result == JFileChooser.APPROVE_OPTION){
+					SelectFNA.this.gbkPathTxt.setText(fileChooser.getSelectedFile().getAbsolutePath());
+				}else{
+					return;
+				}
+			}
+		});
+		
+		browseBtn.setBounds(550, 61, 125, 23);
+		contentPanel.add(browseBtn);
+		downloadRdBtn.addMouseListener(new MouseAdapter() {
+			@Override
+			public void mouseClicked(MouseEvent e) {
+				firstLevelCombo.setEnabled(true);
+				secondLevelCombo.setEnabled(true);
+				downloadBtn.setEnabled(true);
+
+				gbkPathTxt.setEnabled(false);
+				browseBtn.setEnabled(false);
+
+				if (firstLevelCombo.getItemCount() == 0) {
+					firstLevelCombo.addItem("Downloading bacterias list, please wait...");
+
+					(new Thread(new Runnable() {
+						@Override
+						public void run() {
+							// Closed
+							FTPClient ftp = new FTPClient();
+							try {
+								ftp.connect("ftp.ncbi.nih.gov");
+								ftp.enterLocalPassiveMode();
+								ftp.login("anonymous", "");
+								FTPFile[] files = ftp.listFiles("/genomes/archive/old_genbank/Bacteria/");
+
+								firstLevelCombo.removeAllItems();
+								for (FTPFile t : files) {
+									if (!t.getName().contains(".")) {
+										firstLevelCombo.addItem(t.getName());
+									}
+								}
+								secondLevelCombo.addItem("Please Choose Your bacteria First");
+								ftp.disconnect();
+							} catch (IOException e) {
+								logger.error(e.getMessage());
+								return;
+							}
+						}
+					})).start();
+				}
+			}
+		});
+
+		downloadRdBtn.setBounds(22, 94, 401, 23);
+		contentPanel.add(downloadRdBtn);
+		firstLevelCombo.addItemListener(new ItemListener() {
+			@SuppressWarnings("deprecation")
+			@Override
+			public void itemStateChanged(ItemEvent e) {
+				if (e.getStateChange() == ItemEvent.SELECTED) {
+					secondLevelCombo.removeAllItems();
+					secondLevelCombo.addItem("Retieving Files List, Please Wait");
+
+					if (secondLevelThread != null){
+						secondLevelThread.run();
+						secondLevelThread.stop();
+						secondLevelThread = null;
+					}
+					
+					secondLevelThread = new Thread(new Runnable() {
+						private FTPClient ftp = null;
+						
+						@Override
+						public void run() {
+							// Closed
+							if (ftp != null){
+								try {
+									ftp.disconnect();
+								} catch (IOException e) {
+									e.printStackTrace();
+								}
+								return;
+							}
+							
+							ftp = new FTPClient();
+							try {
+								ftp.connect("ftp.ncbi.nih.gov");
+								ftp.enterLocalPassiveMode();
+								ftp.login("anonymous", "");
+								String ftpDir = "/genomes/archive/old_genbank/Bacteria/" + firstLevelCombo.getSelectedItem() + "/";
+								FTPFile[] files = ftp.listFiles(ftpDir);
+								ftp.disconnect();
+
+								secondLevelCombo.removeAllItems();
+								for (FTPFile t : files) {
+									if (secondLevelThread == null){
+										secondLevelCombo.removeAllItems();
+										System.out.println("Break");
+										break;
+									}
+									
+									if (t.getName().endsWith(".fna")) {
+										String fileName = "";
+										String bacteriaName = "";
+										String lengthString = "";
+										String line = "";
+
+										fileName = t.getName().substring(0, t.getName().length() - 4);
+
+										ftp.connect("ftp.ncbi.nih.gov");
+										ftp.enterLocalPassiveMode();
+										ftp.login("anonymous", "");
+										InputStream stream = ftp.retrieveFileStream(ftpDir + fileName + ".gbk");
+										BufferedReader ftpBr = new BufferedReader(new InputStreamReader(stream));
+
+										line = ftpBr.readLine();
+										lengthString = line.split("\\s+")[2];
+
+										line = ftpBr.readLine();
+
+										String tempLine = ftpBr.readLine();
+										if (!tempLine.startsWith("ACCESSION")){
+											line = line + " " + tempLine.replaceAll("\\s+", "");
+										}
+
+										String[] array = line.split("\\s+");
+										for (int i = 1; i < array.length; i++) {
+											bacteriaName = bacteriaName + array[i] + " ";
+										}
+
+										String itemString = String.format("%s: %s (%s bp)", fileName, bacteriaName, lengthString);
+										secondLevelCombo.addItem(itemString);
+
+										ftp.disconnect();
+									}
+									
+									if (secondLevelThread == null){
+										secondLevelCombo.removeAllItems();
+										break;
+									}
+								}
+								
+								if (secondLevelThread != null){
+									secondLevelCombo.setEnabled(true);
+								}
+								
+							} catch (Exception e1) {
+								logger.error(e1.getMessage());
+								return;
+							}
+						}
+					});
+					
+					secondLevelThread.start();
+				}
+			}
+		});
+		
+		firstLevelCombo.setEnabled(false);
+		firstLevelCombo.setBounds(32, 124, 506, 20);
+		contentPanel.add(firstLevelCombo);
+		
+		secondLevelCombo.setEnabled(false);
+		secondLevelCombo.setBounds(32, 155, 506, 20);
+		contentPanel.add(secondLevelCombo);
+		downloadBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				downloadBtn.setText("Wait");
+				downloadBtn.setEnabled(false);
+				downloadBtn.setVisible(false);
+				progressBar.setVisible(true);
+				progressBar.setValue(0);
+
+				(new Thread(new Runnable() {
+					@Override
+					public void run() {
+						// Closed
+						FTPClient ftp = new FTPClient();
+						try {
+							ftp.connect("ftp.ncbi.nih.gov");
+							ftp.enterLocalPassiveMode();
+							ftp.login("anonymous", "");
+							String ftpDir = "/genomes/archive/old_genbank/Bacteria/" + firstLevelCombo.getSelectedItem() + "/";
+							FTPFile[] files = ftp.listFiles(ftpDir);
+
+							File gbkTemp = null;
+							String fileName = (String) secondLevelCombo.getSelectedItem();
+							fileName = fileName.substring(0, fileName.indexOf(":"));
+							for (FTPFile t : files) {
+								if (t.getName().contains(fileName)) {
+									if (t.getName().endsWith("fna")) {
+										gbkTemp = new File(SelectFNA.this.info.getPath() + t.getName());
+										OutputStream fos = new FileOutputStream(gbkTemp);
+										final long fileSize = t.getSize();
+										CopyStreamAdapter csa = new CopyStreamAdapter() {
+											boolean change = true;
+
+											@Override
+											public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
+												int percent = (int) (totalBytesTransferred * 100 / (double) fileSize);
+												if (percent % 5 == 0) {
+													if (change) {
+														change = false;
+														progressBar.setValue(percent);
+													}
+												} else {
+													change = true;
+												}
+											}
+										};
+										ftp.setCopyStreamListener(csa);
+										ftp.retrieveFile(ftpDir + t.getName(), fos);
+										fos.close();
+										gbkPathTxt.setText(gbkTemp.getAbsolutePath());
+									}
+								}
+							}
+							ftp.disconnect();
+
+							downloadBtn.setText("Download");
+							downloadBtn.setVisible(true);
+							downloadBtn.setEnabled(true);
+							progressBar.setVisible(false);
+							firstLevelCombo.setEnabled(true);
+							secondLevelCombo.setEnabled(true);
+
+						} catch (IOException e) {
+							logger.error(e.getMessage());
+							downloadBtn.setEnabled(true);
+							downloadBtn.setText("Try again");
+							return;
+						}
+					}
+				})).start();
+			}
+		});
+		
+		downloadBtn.setEnabled(false);
+		downloadBtn.setBounds(550, 154, 125, 23);
+		contentPanel.add(downloadBtn);
+		
+		JSeparator separator = new JSeparator();
+		separator.setBounds(10, 197, 665, 2);
+		contentPanel.add(separator);
+		{
+			JPanel buttonPane = new JPanel();
+			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
+			getContentPane().add(buttonPane, BorderLayout.SOUTH);
+			{
+				JButton okButton = new JButton("OK");
+				okButton.addActionListener(new ActionListener() {
+					public void actionPerformed(ActionEvent e) {
+						
+						if (gbkPathTxt.getText() == null || gbkPathTxt.getText().equals("")){
+							JOptionPane.showMessageDialog(SelectFNA.this, "Please select a previously downloaded Sequence File or download one from NCBI server.");
+							return;
+						}
+						
+						textfield.setText(gbkPathTxt.getText());
+						SelectFNA.this.setVisible(false);
+						SelectFNA.this.dispose();
+						
+						SelectFNA.this.parent.setVisible(true);
+						JOptionPane.showMessageDialog(SelectFNA.this.parent, "FNA file selected.");
+					}
+				});
+				okButton.setActionCommand("OK");
+				buttonPane.add(okButton);
+				getRootPane().setDefaultButton(okButton);
+			}
+		}
+		
+		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+		setVisible(true);
+		
+		ButtonGroup group1 = new ButtonGroup();
+		group1.add(downloadRdBtn);
+		group1.add(previousRdBtn);
+		
+		previousRdBtn.setSelected(true);
+		
+		progressBar.setStringPainted(true);
+		progressBar.setBounds(550, 161, 125, 14);
+		contentPanel.add(progressBar);
+		
+		setLocationRelativeTo(parent);
+	}
+	
+	public void setFNAPath(String fnaPath){
+		gbkPathTxt.setText(fnaPath);
+	}
+
+}
diff --git a/src/GUI/Utilities.java b/src/GUI/Utilities.java
new file mode 100644
index 0000000..8513dd6
--- /dev/null
+++ b/src/GUI/Utilities.java
@@ -0,0 +1,96 @@
+package GUI;
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+
+import javax.swing.JFrame;
+import javax.swing.JTabbedPane;
+
+public class Utilities {
+
+	private static JFrame frame;
+	private static JTabbedPane panel;
+	private static int newFrameHeight;
+	@SuppressWarnings("unused")
+	private static int newPanelHeigth;
+	private static int step;
+	private static int interval;
+
+	public static void shrinkFrame(JFrame frame, JTabbedPane panel, int newFrameHeight, int newPanelHeigth, int step, int interval){
+
+		Utilities.frame = frame;
+		Utilities.panel = panel;
+		Utilities.newFrameHeight = newFrameHeight;
+		Utilities.newPanelHeigth = newPanelHeigth;
+		Utilities.step = step;
+		Utilities.interval = interval;
+
+		new Thread(new Runnable()
+		{
+			public void run()
+			{
+				Dimension frameDim = Utilities.frame.getSize();
+				Dimension panelDim = Utilities.panel.getSize();
+
+				int step = (int) ((frameDim.getHeight() - Utilities.newFrameHeight) / Utilities.step);
+
+				while (frameDim.getHeight() >= Utilities.newFrameHeight)
+				{
+					try
+					{
+						Utilities.frame.setSize((int)(frameDim.getWidth()), (int)(frameDim.getHeight() - step));
+						Utilities.panel.setSize((int)(panelDim.getWidth()), (int)(panelDim.getHeight() - step));
+						Thread.sleep(Utilities.interval);
+					}
+					catch(InterruptedException ex) 
+					{
+
+					}
+					frameDim = Utilities.frame.getSize();
+					panelDim = Utilities.panel.getSize();
+				}
+			}
+		}).start();
+		
+		Rectangle rec = panel.getBounds();
+		panel.setBounds((int)rec.getX(), (int)rec.getY(), (int)rec.getWidth(), newPanelHeigth);
+	}
+	
+	public static void expandFrame(JFrame frame, JTabbedPane panel, int newFrameHeight, int newPanelHeigth, int step, int interval){
+
+		Utilities.frame = frame;
+		Utilities.panel = panel;
+		Utilities.newFrameHeight = newFrameHeight;
+		Utilities.newPanelHeigth = newPanelHeigth;
+		Utilities.step = step;
+		Utilities.interval = interval;
+
+		new Thread(new Runnable()
+		{
+			public void run()
+			{
+				Dimension frameDim = Utilities.frame.getSize();
+				Dimension panelDim = Utilities.panel.getSize();
+
+				int step = (int) ((Utilities.newFrameHeight - frameDim.getHeight()) / Utilities.step);
+
+				while (frameDim.getHeight() <= Utilities.newFrameHeight)
+				{
+					try
+					{
+						Utilities.frame.setSize((int)(frameDim.getWidth()), (int)(frameDim.getHeight() + step));
+						Utilities.panel.setSize((int)(panelDim.getWidth()), (int)(panelDim.getHeight() + step));
+						Thread.sleep(Utilities.interval);
+					}
+					catch(InterruptedException ex) 
+					{
+
+					}
+					frameDim = Utilities.frame.getSize();
+					panelDim = Utilities.panel.getSize();
+				}
+			}
+		}).start();
+	}
+	
+}
diff --git a/src/GUI/WorkspaceChooser.java b/src/GUI/WorkspaceChooser.java
new file mode 100644
index 0000000..acf370d
--- /dev/null
+++ b/src/GUI/WorkspaceChooser.java
@@ -0,0 +1,406 @@
+package GUI;
+
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JSeparator;
+import javax.swing.border.EmptyBorder;
+
+import org.apache.log4j.Logger;
+
+import CustomGUIComponent.FolderChooser;
+import essgenes.Messages;
+
+ at SuppressWarnings("serial")
+public class WorkspaceChooser extends JFrame {
+
+	private Logger logger = Logger.getLogger(WorkspaceChooser.class.getName());
+	private ArrayList<String> projectPaths = new ArrayList<String>();
+	private ArrayList<String> projectNames = new ArrayList<String>();
+	private JComboBox<String> recentProjects = new JComboBox<String>();
+	private boolean isTrimed = false;
+
+	private JPanel contentPane;
+
+	/**
+	 * Create the frame.
+	 */
+	public WorkspaceChooser() {
+		setTitle("Create/Open Projects");
+		setResizable(false);
+		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+		setBounds(100, 100, 549, 225);
+		contentPane = new JPanel();
+		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
+		setContentPane(contentPane);
+		contentPane.setLayout(null);
+		setLocationRelativeTo(null);
+		recentProjects.setToolTipText("Recently openned projects");
+
+		recentProjects.setBounds(12, 101, 299, 22);
+		contentPane.add(recentProjects);
+
+		trimRecentProjects();
+		
+		if(isTrimed){
+			JOptionPane.showMessageDialog(WorkspaceChooser.this, "Some project were moved or removed since last run.\n"
+					+ "Those projects are removed from your recent projects");
+		}
+		
+		getRecentProjects();
+		for (String temp : projectNames){
+			recentProjects.addItem(temp);
+		}
+
+		JLabel lblChooseOrCreate = new JLabel("Select a project:");
+		lblChooseOrCreate.setFont(new Font("Tahoma", Font.BOLD, 18));
+		lblChooseOrCreate.setBounds(12, 13, 455, 28);
+		contentPane.add(lblChooseOrCreate);
+
+		JLabel lblYouCanHave = new JLabel("You can have multiple projects in this application.");
+		lblYouCanHave.setBounds(12, 54, 507, 16);
+		contentPane.add(lblYouCanHave);
+
+		JButton browseBtn = new JButton("Browse");
+		browseBtn.setToolTipText("Select a folder for the new project");
+		browseBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath().toString();
+				JFileChooser fileChooser = new JFileChooser(location);
+				fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
+				int result = fileChooser.showOpenDialog(WorkspaceChooser.this);
+
+				if (result == JFileChooser.APPROVE_OPTION){
+					File dir = fileChooser.getSelectedFile();
+					File[] matchingFiles = dir.listFiles(new FilenameFilter() {
+						@Override
+						public boolean accept(File dir, String name) {
+							return (name.endsWith(".pro") || name.endsWith(".Pro")); 
+						}
+					});
+					if (matchingFiles.length < 1){
+						JOptionPane.showMessageDialog(WorkspaceChooser.this, "There is no project found in this directory. "
+								+ "You can try to create one!");
+						return;
+					}
+
+					String projectName = "";
+					String projectPath = "";
+					BufferedReader br = null;
+					try{
+						br = new BufferedReader(new FileReader(matchingFiles[0]));
+						String line = br.readLine();
+						projectName = line.substring(Messages.projectName.length());
+
+						line = br.readLine();
+						projectPath = line.substring(Messages.projectPath.length());
+					}catch(IOException e){
+						logger.error(e.getMessage());
+						return;
+					}finally{
+						try {
+							br.close();
+						} catch (IOException e) {
+							logger.error(e.getMessage());
+						}
+					}
+
+					WorkspaceChooser.this.recentProjects.addItem(projectName);
+					WorkspaceChooser.this.recentProjects.setSelectedIndex(WorkspaceChooser.this.recentProjects.getItemCount() - 1);
+
+					projectPath = fileChooser.getSelectedFile().getAbsolutePath();
+					String seperator = "\\";
+					if(projectPath.contains("/")){
+						seperator = "/";
+					}
+					projectPath = projectPath + seperator;
+					
+					addToRecentProjects(projectName, projectPath);
+
+					projectNames.add(projectName);
+					projectPaths.add(projectPath);
+				}
+			}
+		});
+		browseBtn.setBounds(323, 100, 97, 25);
+		contentPane.add(browseBtn);
+
+		JButton newBtn = new JButton("New");
+		newBtn.setToolTipText("Create new project by selecting a folder to store the new project in it");
+		newBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				String projectName = JOptionPane.showInputDialog(WorkspaceChooser.this, "Enter project name:", "Project Name", JOptionPane.CANCEL_OPTION);
+				if(projectName == null || projectName.compareTo("") == 0){
+					return;
+				}
+				
+				Path currentRelativePath = Paths.get("");
+				String location = currentRelativePath.toAbsolutePath().toString();
+				
+				String OSName = System.getProperty("os.name");
+
+				JFileChooser fileChooser = null;
+				int result = -1;
+				if(OSName.contains("Windows") || OSName.contains("windows")){
+					fileChooser = new FolderChooser();
+					fileChooser.setCurrentDirectory(new File(location));
+					fileChooser.setDialogTitle("Select a location for the new project.");
+					result = fileChooser.showSaveDialog(WorkspaceChooser.this);					
+				}else{
+					JOptionPane.showMessageDialog(WorkspaceChooser.this, "Select a location for the new project.");
+					fileChooser = new JFileChooser();
+					fileChooser.setCurrentDirectory(new File(location));
+					fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+					fileChooser.setDialogTitle("Select a location for the new project.");
+					result = fileChooser.showSaveDialog(WorkspaceChooser.this);
+				}
+				
+				if (result == JFileChooser.APPROVE_OPTION){
+					File dir = fileChooser.getSelectedFile();
+					File[] matchedFiles = dir.listFiles(new FilenameFilter() {
+
+						@Override
+						public boolean accept(File dir, String name) {
+							return (name.endsWith(".pro") || name.endsWith(".Pro"));
+						}
+					});
+
+					if (matchedFiles.length != 0){
+						JOptionPane.showMessageDialog(WorkspaceChooser.this, "There is already another project existing "
+								+ "in this directory, choose another one please.");
+						return;
+					}
+					
+					String projectPath = dir.getAbsolutePath();
+					String seperator = "\\";
+					if(projectPath.contains("/")){
+						seperator = "/";
+					}
+					projectPath = projectPath + seperator + projectName + seperator;
+					
+					BufferedWriter bw = null;
+					try{
+						File projectDir = new File(projectPath);
+						projectDir.mkdirs();
+						
+						File projectFile = new File(projectPath + "project.pro");
+						boolean ifCreated = projectFile.createNewFile();
+
+						if(!ifCreated){
+							logger.error("We could not create the project file!!!");
+							return;
+						}else{
+							bw = new BufferedWriter(new FileWriter(projectFile));
+
+							bw.write(Messages.projectName + projectName + "\n");
+							bw.write(Messages.projectPath + projectPath + "\n");
+						}
+
+						bw.close();
+
+						WorkspaceChooser.this.recentProjects.addItem(projectName);
+						WorkspaceChooser.this.recentProjects.setSelectedIndex(WorkspaceChooser.this.recentProjects.getItemCount() - 1);
+
+						projectPaths.add(projectPath);
+						projectNames.add(projectName);
+
+						addToRecentProjects(projectName, projectPath);
+
+					}catch(IOException e){
+						logger.error(e.getMessage());
+						return;
+					}
+
+				}
+			}
+		});
+		newBtn.setBounds(432, 100, 97, 25);
+		contentPane.add(newBtn);
+
+		JButton cancelBtn = new JButton("Cancel");
+		cancelBtn.setToolTipText("Close the application");
+		cancelBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				System.exit(0);
+			}
+		});
+		cancelBtn.setBounds(323, 153, 97, 25);
+		contentPane.add(cancelBtn);
+
+		JButton okBtn = new JButton("OK");
+		okBtn.setToolTipText("Load your project and continue");
+		okBtn.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+
+				String selected =  (String) WorkspaceChooser.this.recentProjects.getSelectedItem();
+				for(int i = 0; i < projectNames.size(); i++){
+					if (selected.compareTo(projectNames.get(i)) == 0){
+						selected = projectPaths.get(i);
+					}
+				}
+
+				MainFrame mainFrame = new MainFrame(selected);
+				mainFrame.setVisible(true);
+
+				WorkspaceChooser.this.setVisible(false);
+				WorkspaceChooser.this.dispose();
+			}
+		});
+		okBtn.setBounds(432, 153, 97, 25);
+		contentPane.add(okBtn);
+		
+		JLabel lblNowYouCan = new JLabel("Choose an existing project or create a new one.");
+		lblNowYouCan.setBounds(12, 72, 497, 16);
+		contentPane.add(lblNowYouCan);
+		
+		JSeparator separator = new JSeparator();
+		separator.setBounds(0, 138, 543, 2);
+		contentPane.add(separator);
+	}
+
+	private void trimRecentProjects(){
+		File projects = new File("projects.dat");
+		File trimmed = new File("temp.dat");
+		BufferedReader br = null;
+		BufferedWriter bw = null;
+		
+		try {
+			if(!projects.exists()){
+				projects.createNewFile();
+			}
+			
+			br = new BufferedReader(new FileReader(projects));
+			bw = new BufferedWriter(new FileWriter(trimmed));
+			String line = br.readLine();
+
+			while(line != null){
+				int tempIndex = line.indexOf(Messages.separatorString);
+				String tempPath = line.substring(tempIndex + Messages.separatorString.length());
+
+				File tempProDir = new File(tempPath);
+				
+				if(tempProDir.exists()){
+					bw.write(line + "\n");
+				}else{
+					isTrimed = true;
+				}
+
+				line = br.readLine();
+			}
+			
+			br.close();
+			bw.close();
+			
+			projects.delete();
+			trimmed.renameTo(projects);
+
+		} catch (FileNotFoundException e) {
+			logger.error(e.getMessage());
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+		}
+	}
+
+	private void addToRecentProjects(String projectName, String projectPath){
+		File projects = new File("projects.dat");
+		BufferedReader br = null;
+		BufferedWriter bw = null;
+		boolean exists = false;
+
+		try {
+			br = new BufferedReader(new FileReader(projects));
+			String line = br.readLine();
+
+			while(line != null){
+				int tempIndex = line.indexOf(Messages.separatorString);
+				//String tempName = line.substring(0, tempIndex);
+				String tempPath = line.substring(tempIndex + Messages.separatorString.length());
+
+				if (projectPath.compareTo(tempPath) == 0){
+					exists = true;
+					break;
+				}
+
+				line = br.readLine();
+			}
+
+			br.close();
+
+			bw = new BufferedWriter(new FileWriter(projects, true));
+			if (!exists){
+				bw.append(projectName + Messages.separatorString + projectPath + "\n");
+			}
+
+			bw.close();
+
+		} catch (FileNotFoundException e) {
+			logger.error(e.getMessage());
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+		}finally{
+			try {
+				br.close();
+				bw.close();
+			} catch (IOException e) {
+				logger.error(e.getMessage());
+			}
+		}
+	}
+
+	private void getRecentProjects(){
+
+		File projects = new File("projects.dat");
+		BufferedReader br = null;
+
+		try {
+			if(!projects.exists()){
+				projects.createNewFile();
+			}
+			
+			br = new BufferedReader(new FileReader(projects));
+			String line = br.readLine();
+
+			while(line != null){
+				int tempIndex = line.indexOf(Messages.separatorString);
+				String tempName = line.substring(0, tempIndex);
+				String tempPath = line.substring(tempIndex + Messages.separatorString.length());
+
+				projectPaths.add(tempPath);
+				projectNames.add(tempName);
+
+				line = br.readLine();
+			}
+
+		} catch (FileNotFoundException e) {
+			logger.error(e.getMessage());
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+		}finally{
+			try {
+				br.close();
+			} catch (IOException e) {
+				logger.error(e.getMessage());
+			}
+		}
+	}
+}
diff --git a/src/UtilityFunctions/FilterTable.java b/src/UtilityFunctions/FilterTable.java
new file mode 100644
index 0000000..71d0a47
--- /dev/null
+++ b/src/UtilityFunctions/FilterTable.java
@@ -0,0 +1,125 @@
+package UtilityFunctions;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class FilterTable {
+
+	public static void main(String[] args) throws IOException {
+		
+		File tableCompare = new File("C:\\Users\\sina\\Desktop\\Essential Genes\\data\\Compare\\SupplementaryFile2-00.xls");
+		File knownEssentials = new File("C:\\Users\\sina\\Desktop\\Essential Genes\\data\\known-essentials.xls");
+		File knownNonEssentials = new File("C:\\Users\\sina\\Desktop\\Essential Genes\\data\\known-non-essentials.xls");
+		File output = new File("C:\\Users\\sina\\Desktop\\Essential Genes\\data\\Compare\\result.xls");
+		
+		String line = "";
+
+		/////////////////////////////////////////////////////////////////////////////////
+		
+		BufferedReader br = new BufferedReader(new FileReader(knownEssentials));
+		for (int i = 0; i < 3; i++){
+			line = br.readLine();
+		}
+		
+		line = br.readLine();
+		ArrayList<String> knownEssentialsList = new ArrayList<String>();
+		while(line != null){
+			for (int i = 0; i < 6; i++){
+				line = line.substring(line.indexOf("\t") + 1);
+			}
+
+			String mmpNum = line.substring(0, line.indexOf("\t"));
+			
+			knownEssentialsList.add(mmpNum);
+			
+			line = br.readLine();
+		}
+		br.close();
+		
+		/////////////////////////////////////////////////////////////////////////////////
+		
+		br = new BufferedReader(new FileReader(knownNonEssentials));
+		for (int i = 0; i < 3; i++){
+			line = br.readLine();
+		}
+
+		line = br.readLine();
+		ArrayList<String> knownNonEssentialsList = new ArrayList<String>();
+		while(line != null){
+			for (int i = 0; i < 6; i++){
+				line = line.substring(line.indexOf("\t") + 1);
+			}
+
+			String mmpNum = line.substring(0, line.indexOf("\t"));
+			knownNonEssentialsList.add(mmpNum);
+			
+			line = br.readLine();
+		}
+		br.close();
+		
+		/////////////////////////////////////////////////////////////////////////////////
+
+		BufferedWriter bw = new BufferedWriter(new FileWriter(output));
+		
+		StringBuilder header = new StringBuilder();
+		br = new BufferedReader(new FileReader(tableCompare));
+		for (int i = 0; i < 4; i++){
+			line = br.readLine();
+			header.append(line + "\n");
+		}
+		
+		bw.write(header.toString());
+		
+		line = br.readLine();
+		while(line != null){
+			GeneHolder gene = new GeneHolder();
+			gene.setCompleteLine(new String(line));
+		
+			for (int i = 0; i < 3; i++){
+				line = line.substring(line.indexOf("\t") + 1);
+			}
+			gene.setMmpNum(line.substring(0, line.indexOf("\t")));
+			
+			if (knownEssentialsList.contains(gene.getMmpNum())){
+				bw.write(gene.getCompleteLine() + "+\n");
+			}else if (knownNonEssentialsList.contains(gene.getMmpNum())){
+				bw.write(gene.getCompleteLine() + "-\n");
+			}else{
+				bw.write(gene.getCompleteLine() + "\n");
+			}
+			
+			line = br.readLine();
+		}
+		br.close();
+		bw.close();
+		
+	}
+	
+	private static class GeneHolder{
+		private String completeLine;
+		private String mmpNum;
+		
+		public GeneHolder(){
+			
+		}
+		
+		public String getCompleteLine() {
+			return completeLine;
+		}
+		public void setCompleteLine(String completeLine) {
+			this.completeLine = completeLine;
+		}
+		public String getMmpNum() {
+			return mmpNum;
+		}
+		public void setMmpNum(String mmpNum) {
+			this.mmpNum = mmpNum;
+		}
+	}
+	
+}
diff --git a/src/essgenes/AddColumns.java b/src/essgenes/AddColumns.java
new file mode 100644
index 0000000..ef5672a
--- /dev/null
+++ b/src/essgenes/AddColumns.java
@@ -0,0 +1,1036 @@
+package essgenes;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JOptionPane;
+import javax.swing.JProgressBar;
+import javax.swing.table.DefaultTableModel;
+
+import org.apache.log4j.Logger;
+
+import GUI.ProgressBarUpdater;
+
+public class AddColumns {
+
+	private static Logger logger = Logger.getLogger(AddColumns.class.getName());
+
+	@SuppressWarnings("resource")
+	public static String countInsertions(String libName, String tableName, String adjustStartString, String adjustEndString, boolean ifUniqueInsertions, ProjectInfo info) throws IOException{
+
+		int adjustStart;
+		double adjustStartPercent;
+		int adjustEnd;
+		double adjustEndPercent;
+
+		if (adjustStartString.contains("%")){
+			if (!adjustEndString.contains("%")){
+				JOptionPane.showMessageDialog(null, "Both adjustment numbers should either be in percents or be absolute values.");
+				return "Both adjustment numbers should either be in percents or be absolute values.";
+			}
+			
+			adjustStart = 0;
+			adjustStartPercent = Integer.parseInt(adjustStartString.substring(0, adjustStartString.length() - 1)) / 100.0;
+			
+			adjustEnd = 0;
+			adjustEndPercent = Integer.parseInt(adjustEndString.substring(0, adjustEndString.length() - 1)) / 100.0;
+		}else{
+			if (!adjustEndString.contains("%")){
+				JOptionPane.showMessageDialog(null, "Both adjustment numbers should either be in percents or be absolute values.");
+				return "Both adjustment numbers should either be in percents or be absolute values.";
+			}
+			
+			adjustStart = Integer.parseInt(adjustStartString);
+			adjustStartPercent = 0.0;
+			
+			adjustEnd = Integer.parseInt(adjustEndString);
+			adjustEndPercent = 0.0;
+		}
+
+		int LSeq = info.getSequenceLen();
+
+		File libFile = new File(info.getPath() + libName + ".inspou");
+		BufferedReader br = new BufferedReader(new FileReader(libFile));
+
+		ArrayList<Integer> insertions = new ArrayList<Integer>();
+		for (int i = 0; i <= LSeq; i++){
+			insertions.add(0);
+		}
+
+		String line = br.readLine();
+		while(line != null){
+			int tempPos = Integer.parseInt(line.substring(0, line.indexOf("\t")));
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			int tempNum = Integer.parseInt(line);
+			if (tempPos > LSeq){
+				JOptionPane.showMessageDialog(null, "ERROR: insertion at position " + tempPos + " whereas chromosome length is " + LSeq + ".", "Error", JOptionPane.ERROR_MESSAGE);
+				return Messages.failMsg;
+			}
+
+			if (ifUniqueInsertions){
+				insertions.set(tempPos, insertions.get(tempPos) + 1);
+			}else{
+				insertions.set(tempPos, insertions.get(tempPos) + tempNum);
+			}
+			line = br.readLine();
+		}
+
+		br.close();
+		File tableFile = new File(info.getPath() + tableName + ".table.xls"); //REPLACE
+		br = new BufferedReader(new FileReader(tableFile));
+
+		File newTableFile = new File(info.getPath() + tableName + ".new");
+		BufferedWriter bw = new BufferedWriter(new FileWriter(newTableFile));
+
+		//Writing File Header at First
+		line = br.readLine();
+		bw.write(line + "\t" + "" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + "" + "\n");
+
+		line = br.readLine();
+		if (ifUniqueInsertions){
+			bw.write(line + "\tunique_insertion_counts: " + libName + "\n");
+		}else{
+			bw.write(line + "\tall_reads_counts: " + libName + "\n");
+		}
+
+		line = br.readLine();
+		bw.write(line + "\t" + adjustStartString + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + adjustEndString + "\n");
+
+		//Reading Main Data and Process it
+		line = br.readLine();
+		while(line != null){
+			String tempLine = new String(line);
+			Tabs gene = new Tabs(tempLine);
+
+			int GeneL = gene.getStart_coord();
+			int GeneR = gene.getEnd_coord();
+
+			int start = gene.getStart_coord();
+			int end = gene.getEnd_coord();
+			int geneLen = end - start + 1;
+			if (gene.getStrand().compareTo("+") == 0){
+				start = GeneL - adjustStart;
+				end = GeneR + adjustEnd;
+				geneLen = end - start + 1;
+				start = (int) (GeneL - adjustStartPercent * geneLen);
+				end = (int) (GeneR + adjustEndPercent * geneLen);
+			}else if (gene.getStrand().compareTo("-") == 0){
+				start = GeneL - adjustEnd;
+				end = GeneR + adjustStart;
+				geneLen = end - start + 1;
+				start = (int) (GeneL - adjustEndPercent * geneLen);
+				end = (int) (GeneR + adjustStartPercent * geneLen);
+			}else{
+				logger.error("Gene strand is not + or -  ...  skipping end adjustments");
+			}
+
+			if  (Math.abs(adjustEnd) + Math.abs(adjustStart) < geneLen){
+				int count = 0;
+				for (int i = start; i <= end; i++){
+					count += insertions.get(i);
+				}
+
+				bw.write(line + "\t" + count + "\n");
+			}else{
+				bw.write(line + "\t" + Double.NaN + "\n");
+			}
+
+			line = br.readLine();
+		}
+
+		br.close();
+		bw.close();
+
+		if(tableFile.delete()){
+			if(newTableFile.renameTo(tableFile)){
+				return Messages.successMsg;
+			}
+		}
+
+		return Messages.failMsg;
+	}
+
+	@SuppressWarnings("resource")
+	public static String calcInsertionDensity(String libName, String tableName, String adjustStartString, String adjustEndString, boolean ifUniqueInsertions, ProjectInfo info) throws IOException{
+
+		int adjustStart;
+		double adjustStartPercent;
+		int adjustEnd;
+		double adjustEndPercent;
+
+		if (adjustStartString.contains("%")){
+			if (!adjustEndString.contains("%")){
+				JOptionPane.showMessageDialog(null, "Both adjustment numbers should either be in percents or be absolute values.");
+				return "Both adjustment numbers should either be in percents or be absolute values.";
+			}
+			
+			adjustStart = 0;
+			adjustStartPercent = Integer.parseInt(adjustStartString.substring(0, adjustStartString.length() - 1)) / 100.0;
+			
+			adjustEnd = 0;
+			adjustEndPercent = Integer.parseInt(adjustEndString.substring(0, adjustEndString.length() - 1)) / 100.0;
+			
+			if (adjustEndPercent + adjustStartPercent >= 100){
+				JOptionPane.showMessageDialog(null, "Summation of Start and End adjustment percents cannot be greater than or equal to 100.");
+				return Messages.failMsg;
+			}
+		}else{
+			if (adjustEndString.contains("%")){
+				JOptionPane.showMessageDialog(null, "Both adjustment numbers should either be in percents or be absolute values.");
+				return "Both adjustment numbers should either be in percents or be absolute values.";
+			}
+			
+			adjustStart = Integer.parseInt(adjustStartString);
+			adjustStartPercent = 0.0;
+			
+			adjustEnd = Integer.parseInt(adjustEndString);
+			adjustEndPercent = 0.0;
+		}
+
+		int LSeq = info.getSequenceLen();
+		
+		File libFile = new File(info.getPath() + libName + ".inspou");
+		BufferedReader br = new BufferedReader(new FileReader(libFile));
+
+		ArrayList<Integer> insertions = new ArrayList<Integer>();
+		for (int i = 0; i <= LSeq; i++){
+			insertions.add(0);
+		}
+
+		String line = br.readLine();
+		while(line != null){
+			int tempPos = Integer.parseInt(line.substring(0, line.indexOf("\t")));
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			int tempNum = Integer.parseInt(line);
+			if (tempPos > LSeq){
+				JOptionPane.showMessageDialog(null, "ERROR: insertion at position " + tempPos + " whereas chromosome length is " + LSeq + ".", "Error", JOptionPane.ERROR_MESSAGE);
+				return Messages.failMsg;
+			}
+
+			if (ifUniqueInsertions){
+				insertions.set(tempPos, insertions.get(tempPos) + 1);
+			}else{
+				insertions.set(tempPos, insertions.get(tempPos) + tempNum);
+			}
+			line = br.readLine();
+		}
+
+		br.close();
+		File tableFile = new File(info.getPath() + tableName + ".table.xls"); //REPLACE
+		br = new BufferedReader(new FileReader(tableFile));
+
+		File newTableFile = new File(info.getPath() + tableName + ".new");
+		BufferedWriter bw = new BufferedWriter(new FileWriter(newTableFile));
+
+		//Writing File Header at First
+		line = br.readLine();
+		bw.write(line + "\t" + "" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + "" + "\n");
+
+		line = br.readLine();
+		if (ifUniqueInsertions){
+			bw.write(line + "\tunique_insertion_density: " + libName + "\n");
+		}else{
+			bw.write(line + "\tall_reads_density: " + libName + "\n");
+		}
+
+		line = br.readLine();
+		bw.write(line + "\t" + adjustStartString + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + adjustEndString + "\n");
+
+		//Reading Main Data and Process it
+		line = br.readLine();
+		while(line != null){
+			String tempLine = new String(line);
+			Tabs gene = new Tabs(tempLine);
+
+			int GeneL = gene.getStart_coord();
+			int GeneR = gene.getEnd_coord();
+
+			int start = gene.getStart_coord();
+			int end = gene.getEnd_coord();
+			int geneLen = end - start + 1;
+			if (gene.getStrand().compareTo("+") == 0){
+				start = GeneL - adjustStart;
+				end = GeneR + adjustEnd;
+				geneLen = end - start + 1;
+				start = (int) (GeneL - adjustStartPercent * geneLen);
+				end = (int) (GeneR + adjustEndPercent * geneLen);
+			}else if (gene.getStrand().compareTo("-") == 0){
+				start = GeneL - adjustEnd;
+				end = GeneR + adjustStart;
+				geneLen = end - start + 1;
+				start = (int) (GeneL - adjustEndPercent * geneLen);
+				end = (int) (GeneR + adjustStartPercent * geneLen);
+			}else{
+				logger.error("Gene strand is not + or -  ...  skipping end adjustments");
+			}
+
+			if  (Math.abs(adjustEnd) + Math.abs(adjustStart) < geneLen){
+				int count = 0;
+				for (int i = start; i <= end; i++){
+					count += insertions.get(i);
+				}
+
+				bw.write(line + "\t" + ((double)count / geneLen) + "\n");
+			}else{
+				bw.write(line + "\t" + Double.NaN + "\n");
+			}
+
+			line = br.readLine();
+		}
+
+		br.close();
+		bw.close();
+
+		if(tableFile.delete()){
+			if(newTableFile.renameTo(tableFile)){
+				return Messages.successMsg;
+			}
+		}else{
+			if(tableFile.delete()){
+				if(newTableFile.renameTo(tableFile)){
+					return Messages.successMsg;
+				}
+			}
+		}
+
+		return Messages.failMsg;
+	}
+	
+	@SuppressWarnings("resource")
+	public static String calcInsertionDensityTA(String libName, String tableName, String adjustStartString, String adjustEndString, boolean ifUniqueInsertions, String fnaPath, ProjectInfo info) throws IOException{
+
+		File fnaFile = new File(fnaPath);
+		BufferedReader fnaBr = new BufferedReader(new FileReader(fnaFile));
+		
+		StringBuffer sb = new StringBuffer();
+		String fnaLine = fnaBr.readLine();
+		fnaLine = fnaBr.readLine();
+		
+		while(fnaLine != null){
+			sb.append(fnaLine.toUpperCase());
+			fnaLine = fnaBr.readLine();
+		}
+		fnaBr.close();
+		
+		fnaLine = sb.toString();
+		
+		List<Integer> taSite = new ArrayList<Integer>();
+		for (int i = 0; i < fnaLine.length() - 1; i++){
+			if ((fnaLine.charAt(i) == 'T' && fnaLine.charAt(i + 1) == 'A')){
+				taSite.add(1);
+			}else{
+				taSite.add(0);
+			}
+		}
+		
+		int adjustStart;
+		double adjustStartPercent;
+		int adjustEnd;
+		double adjustEndPercent;
+
+		if (adjustStartString.contains("%")){
+			if (!adjustEndString.contains("%")){
+				JOptionPane.showMessageDialog(null, "Both adjustment numbers should either be in percents or be absolute values.");
+				return "Both adjustment numbers should either be in percents or be absolute values.";
+			}
+			
+			adjustStart = 0;
+			adjustStartPercent = Integer.parseInt(adjustStartString.substring(0, adjustStartString.length() - 1)) / 100.0;
+			
+			adjustEnd = 0;
+			adjustEndPercent = Integer.parseInt(adjustEndString.substring(0, adjustEndString.length() - 1)) / 100.0;
+			
+			if (adjustEndPercent + adjustStartPercent >= 100){
+				JOptionPane.showMessageDialog(null, "Summation of Start and End adjustment percents cannot be greater than or equal to 100.");
+				return Messages.failMsg;
+			}
+		}else{
+			if (adjustEndString.contains("%")){
+				JOptionPane.showMessageDialog(null, "Both adjustment numbers should either be in percents or be absolute values.");
+				return "Both adjustment numbers should either be in percents or be absolute values.";
+			}
+			
+			adjustStart = Integer.parseInt(adjustStartString);
+			adjustStartPercent = 0.0;
+			
+			adjustEnd = Integer.parseInt(adjustEndString);
+			adjustEndPercent = 0.0;
+		}
+
+		int LSeq = info.getSequenceLen();
+		
+		File libFile = new File(info.getPath() + libName + ".inspou");
+		BufferedReader br = new BufferedReader(new FileReader(libFile));
+
+		ArrayList<Integer> insertions = new ArrayList<Integer>();
+		for (int i = 0; i <= LSeq; i++){
+			insertions.add(0);
+		}
+
+		String line = br.readLine();
+		while(line != null){
+			int tempPos = Integer.parseInt(line.substring(0, line.indexOf("\t")));
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			int tempNum = Integer.parseInt(line);
+			if (tempPos > LSeq){
+				JOptionPane.showMessageDialog(null, "ERROR: insertion at position " + tempPos + " whereas chromosome length is " + LSeq + ".", "Error", JOptionPane.ERROR_MESSAGE);
+				return Messages.failMsg;
+			}
+
+			if (ifUniqueInsertions){
+				insertions.set(tempPos, insertions.get(tempPos) + 1);
+			}else{
+				insertions.set(tempPos, insertions.get(tempPos) + tempNum);
+			}
+			line = br.readLine();
+		}
+
+		br.close();
+		File tableFile = new File(info.getPath() + tableName + ".table.xls"); //REPLACE
+		br = new BufferedReader(new FileReader(tableFile));
+
+		File newTableFile = new File(info.getPath() + tableName + ".new");
+		BufferedWriter bw = new BufferedWriter(new FileWriter(newTableFile));
+
+		//Writing File Header at First
+		line = br.readLine();
+		bw.write(line + "\t" + "" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + "" + "\n");
+
+		line = br.readLine();
+		if (ifUniqueInsertions){
+			bw.write(line + "\tunique_insertion_density_TA: " + libName + "\n");
+		}else{
+			bw.write(line + "\tall_reads_density_TA: " + libName + "\n");
+		}
+
+		line = br.readLine();
+		bw.write(line + "\t" + adjustStartString + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + adjustEndString + "\n");
+
+		//Reading Main Data and Process it
+		line = br.readLine();
+		while(line != null){
+			String tempLine = new String(line);
+			Tabs gene = new Tabs(tempLine);
+
+			int GeneL = gene.getStart_coord();
+			int GeneR = gene.getEnd_coord();
+
+			int start = gene.getStart_coord();
+			int end = gene.getEnd_coord();
+			int geneLen = end - start + 1;
+			if (gene.getStrand().compareTo("+") == 0){
+				start = GeneL - adjustStart;
+				end = GeneR + adjustEnd;
+				geneLen = end - start + 1;
+				start = (int) (GeneL - adjustStartPercent * geneLen);
+				end = (int) (GeneR + adjustEndPercent * geneLen);
+			}else if (gene.getStrand().compareTo("-") == 0){
+				start = GeneL - adjustEnd;
+				end = GeneR + adjustStart;
+				geneLen = end - start + 1;
+				start = (int) (GeneL - adjustEndPercent * geneLen);
+				end = (int) (GeneR + adjustStartPercent * geneLen);
+			}else{
+				logger.error("Gene strand is not + or -  ...  skipping end adjustments");
+			}
+
+			if  (Math.abs(adjustEnd) + Math.abs(adjustStart) < geneLen){
+				int count = 0;
+				int countTA = 0;
+				for (int i = start; i <= end; i++){
+					count += insertions.get(i);
+					countTA += taSite.get(i);
+				}
+
+				if (countTA == 0){
+					bw.write(line + "\t" + Double.NaN + "\n");
+				}else{
+					bw.write(line + "\t" + ((double)count / countTA) + "\n");
+				}
+			}else{
+				bw.write(line + "\t" + Double.NaN + "\n");
+			}
+
+			line = br.readLine();
+		}
+
+		br.close();
+		bw.close();
+		fnaBr.close();
+
+		if(tableFile.delete()){
+			if(newTableFile.renameTo(tableFile)){
+				return Messages.successMsg;
+			}
+		}else{
+			if(tableFile.delete()){
+				if(newTableFile.renameTo(tableFile)){
+					return Messages.successMsg;
+				}
+			}
+		}
+
+		return Messages.failMsg;
+	}
+
+	public static String add(String libName, String tableName, int windowLen, int step, String adjustStartString, String adjustEndString, int seqLen, boolean ifUniqueInsertions, JProgressBar progressBar, ProjectInfo info) throws IOException {
+
+		int adjustStart;
+		double adjustStartPercent;
+		int adjustEnd;
+		double adjustEndPercent;
+
+		if (adjustStartString.contains("%")){
+			if (!adjustEndString.contains("%")){
+				JOptionPane.showMessageDialog(null, "Both adjustment numbers should either be in percents or be absolute values.");
+				return "Both adjustment numbers should either be in percents or be absolute values.";
+			}
+			
+			adjustStart = 0;
+			adjustStartPercent = Integer.parseInt(adjustStartString.substring(0, adjustStartString.length() - 1)) / 100.0;
+			
+			adjustEnd = 0;
+			adjustEndPercent = Integer.parseInt(adjustEndString.substring(0, adjustEndString.length() - 1)) / 100.0;
+			
+			if (adjustEndPercent + adjustStartPercent >= 100){
+				JOptionPane.showMessageDialog(null, "Summation of Start and End adjustment percents cannot be greater than or equal to 100.");
+				return Messages.failMsg;
+			}
+		}else{
+			if (adjustEndString.contains("%")){
+				JOptionPane.showMessageDialog(null, "Both adjustment numbers should either be in percents or be absolute values.");
+				return "Both adjustment numbers should either be in percents or be absolute values.";
+			}
+			
+			adjustStart = Integer.parseInt(adjustStartString);
+			adjustStartPercent = 0.0;
+			
+			adjustEnd = Integer.parseInt(adjustEndString);
+			adjustEndPercent = 0.0;
+		}
+
+		File libFile = new File(info.getPath() + libName + ".inspou");
+		BufferedReader br = new BufferedReader(new FileReader(libFile));
+
+		ArrayList<Integer> insertions = new ArrayList<Integer>();
+		ArrayList<Integer> numberOfReads = new ArrayList<Integer>();
+		String line = br.readLine();
+		while(line != null){
+			insertions.add(Integer.parseInt(line.substring(0, line.indexOf("\t"))));
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			numberOfReads.add(Integer.parseInt(line));
+			line = br.readLine();
+		}
+		br.close();
+
+		int size = seqLen;
+		ProgressBarUpdater pbu = new ProgressBarUpdater(progressBar, size);
+		Thread thread = new Thread(pbu);
+		thread.start();
+
+		ArrayList<Window> windows = new ArrayList<Window>();
+		for (int i = 1; i <= seqLen; i += step){	
+			Window temp = new Window();
+			temp.start = i;
+			pbu.setCurrent(i);
+
+			int LL = i + windowLen - 1;
+			int N = 0;
+
+			if(LL < seqLen){
+				for (int j = 0; j < insertions.size(); j++){
+					if(insertions.get(j) > i && insertions.get(j) <= LL){
+						if (ifUniqueInsertions){
+							N++;	
+						}else{
+							N += numberOfReads.get(j);
+						}
+					}
+				}
+			}else{
+				for (int j = 0; j < insertions.size(); ++j){
+					if(insertions.get(j) > i && insertions.get(j) <= seqLen){
+						if (ifUniqueInsertions){
+							N++;	
+						}else{
+							N += numberOfReads.get(j);
+						}
+					}
+					if(insertions.get(j) <= LL - seqLen){
+						if (ifUniqueInsertions){
+							N++;	
+						}else{
+							N += numberOfReads.get(j);
+						}
+					}
+				}
+			}
+
+			temp.N = N;
+			windows.add(temp);
+		}
+		pbu.setCurrent(-1);
+
+		File tableFile = new File(info.getPath() + tableName + ".table.xls"); //REPLACE
+		br = new BufferedReader(new FileReader(tableFile));
+
+		File newTableFile = new File(info.getPath() + tableName + ".new");
+		BufferedWriter bw = new BufferedWriter(new FileWriter(newTableFile));
+
+		//Writing File Header at First
+		line = br.readLine();
+		if (ifUniqueInsertions){
+			bw.write(line + "\tEssentiality indices:" + libName + "(Counting Unique Insertions)\n");
+		}else{
+			bw.write(line + "\tEssentiality indices:" + libName + "(Counting All Reads)\n");
+		}
+
+		line = br.readLine();
+		bw.write(line + "\t" + windowLen + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + step + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + adjustStartString + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + adjustEndString + "\n");
+
+		//Reading Main Data and Process it
+		line = br.readLine();
+		while(line != null){
+			String tempLine = new String(line);
+			Tabs gene = new Tabs(tempLine);
+
+			int start = gene.getStart_coord();
+			int end = gene.getEnd_coord();
+			int geneLen = end - start + 1;
+
+			if(gene.getStrand().compareTo("+") == 0){
+				start = gene.getStart_coord() - adjustStart;
+				end = gene.getEnd_coord() + adjustEnd;
+				geneLen = end - start + 1;
+				start = (int) (gene.getStart_coord() - adjustStartPercent * geneLen);
+				end = (int) (gene.getEnd_coord() + adjustEndPercent * geneLen);
+			}else if(gene.getStrand().compareTo("-") == 0){
+				start = gene.getStart_coord() - adjustEnd;
+				end = gene.getEnd_coord() + adjustStart;
+				geneLen = end - start + 1;
+				start = (int) (gene.getStart_coord() - adjustEndPercent * geneLen);
+				end = (int) (gene.getEnd_coord() + adjustStartPercent * geneLen);
+			}else{
+				logger.info("Gene strand is not + or - ... skipping end adjustment");
+			}
+
+			int LI = ((int) ((double) (end - windowLen + 1) / step)) + 1;
+			int LJ = ((int) ((double) (start) / step));
+			int N = 0;
+			if (LJ < LI){		//Gene is larger than the window
+				geneLen = LJ;
+				LJ = LI;
+				LI = geneLen;
+
+				if(LJ > windows.size()){
+					break;
+				}
+				N = windows.get(LJ).N;
+				for(geneLen = LI; geneLen <= LJ; ++geneLen){
+					if(geneLen > 0){
+						if(windows.get(geneLen).N > N){
+							N = windows.get(geneLen).N;
+						}
+					}else{
+						int LL = windows.size() + geneLen;
+						if(LL < windows.size() && windows.get(LL).N > N){
+							N = windows.get(LL).N;
+						}
+					}
+				}
+			}else{				//Gene is smaller than the window
+				if(LJ >= windows.size()){
+					JOptionPane.showMessageDialog(null, "Please check all the libraries and the sequence length and try again!");
+				}
+				N = windows.get(LJ).N;
+				for (geneLen = LI; geneLen <= LJ; ++geneLen){
+					if (geneLen >= 0){
+						if(windows.get(geneLen).N < N){
+							N = windows.get(geneLen).N;
+						}
+					}else{
+						int LL = windows.size() + geneLen;
+						if(windows.get(LL).N < N){
+							N = windows.get(LL).N;
+						}
+					}
+				}
+			}
+
+			bw.write(line + "\t" + N + "\n");
+			bw.flush();
+
+			line = br.readLine();
+
+		}
+
+		br.close();
+		bw.close();
+
+		if(tableFile.delete()){
+			if(newTableFile.renameTo(tableFile)){
+				return Messages.successMsg;
+			}
+		}
+
+		return Messages.failMsg;
+	}
+
+	private static class Window{
+		@SuppressWarnings("unused")
+		public int start;
+		public int N;
+	}
+
+	@SuppressWarnings("unused")
+	private static class Tabs{
+		private int start_coord;
+		private int end_coord;
+		private String strand;
+		private int length;
+		private String locus_type;
+		private String locus_tag;
+		private String gene_symbol;
+		private String description;
+
+		public Tabs(String line){
+			String temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			setStart_coord(Integer.parseInt(temp));
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			setEnd_coord(Integer.parseInt(temp));
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			setStrand(temp);
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			setLength(Integer.parseInt(temp));
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			setLocus_type(temp);
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			setLocus_tag(temp);
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			setGene_symbol(temp);
+
+			setDescription(line);			
+		}
+
+		public String getDescription() {
+			return description;
+		}
+		public void setDescription(String description) {
+			this.description = description;
+		}
+		public String getGene_symbol() {
+			return gene_symbol;
+		}
+		public void setGene_symbol(String gene_symbol) {
+			this.gene_symbol = gene_symbol;
+		}
+		public String getLocus_tag() {
+			return locus_tag;
+		}
+		public void setLocus_tag(String locus_tag) {
+			this.locus_tag = locus_tag;
+		}
+		public String getLocus_type() {
+			return locus_type;
+		}
+		public void setLocus_type(String locus_type) {
+			this.locus_type = locus_type;
+		}
+		public int getLength() {
+			return length;
+		}
+		public void setLength(int length) {
+			this.length = length;
+		}
+		public String getStrand() {
+			return strand;
+		}
+		public void setStrand(String strand) {
+			this.strand = strand;
+		}
+		public int getEnd_coord() {
+			return end_coord;
+		}
+		public void setEnd_coord(int end_coord) {
+			this.end_coord = end_coord;
+		}
+		public int getStart_coord() {
+			return start_coord;
+		}
+		public void setStart_coord(int start_coord) {
+			this.start_coord = start_coord;
+		}
+	}
+
+
+	public static DefaultTableModel getHeaderData(String tableName, ProjectInfo info) throws IOException {
+		File tableFile = new File(info.getPath() + tableName + ".table.xls"); //REPLACE
+		BufferedReader br = new BufferedReader(new FileReader(tableFile));
+
+		ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>();
+
+		String line = br.readLine();
+		int lineCount = 0;
+		while(line != null){
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			if (line.contains("\t"))
+				line = line.substring(line.indexOf("\t") + 1);
+			else{
+				JOptionPane.showMessageDialog(null, "The table is empty and there is no data to compare");
+				br.close();
+				return null;
+			}
+
+			ArrayList<String> row = new ArrayList<String>();
+
+			while(line.contains("\t")){
+				String temp = line.substring(0, line.indexOf("\t"));
+				line = line.substring(line.indexOf("\t") + 1);
+
+				row.add(temp);
+			}
+			row.add(line);
+			data.add(row);
+
+			line = br.readLine();
+
+			lineCount++;
+			if(lineCount > 4){
+				break;
+			}
+		}
+
+		br.close();
+
+		int columnCount = data.get(0).size();
+		int rowCount = data.size();
+
+		String[][] result = new String[rowCount][columnCount + 1];
+		for (int i = 0; i < rowCount; i++){
+			result[i][0] = getInfo(i);
+			for (int j = 0; j < columnCount; j++){
+				result[i][j + 1] = data.get(i).get(j);
+			}
+		}
+
+		String[] columnNames = new String[columnCount + 1];
+		columnNames[0] = "Info";
+		for (int i = 1; i < columnCount + 1; i++){
+			columnNames[i] = (i) + "";
+		}
+
+
+		return new DefaultTableModel(result, columnNames);
+	}
+
+	private static String getInfo(int i) {
+		switch (i){
+		case 0:
+			return "Library Name";
+		case 1:
+			return "Window Size";
+		case 2:
+			return "Window Step";
+		case 3:
+			return "Start Adj.";
+		case 4:
+			return "End Adj.";
+		default:
+			return "ERROR";
+		}
+	}
+
+	public static String compareColumnsRatio(String tableName, int firstColumn, int secondColumn, double maxIns, ProjectInfo info) throws IOException {
+		if (maxIns < 1){
+			maxIns = Double.MAX_VALUE;
+		}
+		
+		File tableFile = new File(info.getPath() + tableName + ".table.xls"); //REPLACE
+		BufferedReader br = new BufferedReader(new FileReader(tableFile));
+
+		File newTableFile = new File(info.getPath() + tableName + ".new");
+		BufferedWriter bw = new BufferedWriter(new FileWriter(newTableFile));
+
+		//Writing File Header at First
+		String line = br.readLine();
+		bw.write(line + "\t" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + "Compare" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + firstColumn + " _ " + secondColumn + "\n");
+
+		//Reading Main Data and Process it
+		line = br.readLine();
+		while(line != null){
+			String tempLine = new String(line);
+			ArrayList<String> tabs = tabsForCompare(line);
+
+			double one = Double.parseDouble(tabs.get(firstColumn + 7));
+			double two = Double.parseDouble(tabs.get(secondColumn + 7));
+
+			if (one > maxIns){
+				one = maxIns;
+			}
+
+			if (two > maxIns){
+				two = maxIns;
+			}
+			
+			String numb = String.format("%.5f", ((double) one / (double) two));
+
+			bw.write(tempLine + "\t" +  numb + "\n");
+
+			line = br.readLine();
+		}
+
+		bw.close();
+		br.close();
+
+		if (tableFile.delete()){
+			if(newTableFile.renameTo(tableFile)){
+				return Messages.successMsg;
+			}
+		}
+
+		return Messages.failMsg;
+	}
+	
+	public static String compareColumnsDiff(String tableName, int firstColumn, int secondColumn, double maxIns, ProjectInfo info) throws IOException {
+
+		if (maxIns < 1){
+			maxIns = Double.MAX_VALUE;
+		}		
+		
+		File tableFile = new File(info.getPath() + tableName + ".table.xls"); //REPLACE
+		BufferedReader br = new BufferedReader(new FileReader(tableFile));
+
+		File newTableFile = new File(info.getPath() + tableName + ".new");
+		BufferedWriter bw = new BufferedWriter(new FileWriter(newTableFile));
+
+		//Writing File Header at First
+		String line = br.readLine();
+		bw.write(line + "\t" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + "Compare" + "\n");
+
+		line = br.readLine();
+		bw.write(line + "\t" + firstColumn + " _ " + secondColumn + "\n");
+
+		//Reading Main Data and Process it
+		line = br.readLine();
+		while(line != null){
+			String tempLine = new String(line);
+			ArrayList<String> tabs = tabsForCompare(line);
+
+			double one = Double.parseDouble(tabs.get(firstColumn + 7));
+			double two = Double.parseDouble(tabs.get(secondColumn + 7));
+
+			if (one > maxIns){
+				one = maxIns;
+			}
+
+			if (two > maxIns){
+				two = maxIns;
+			}
+
+			bw.write(tempLine + "\t" + (one - two) + "\n");
+
+			line = br.readLine();
+		}
+
+		bw.close();
+		br.close();
+
+		if (tableFile.delete()){
+			if(newTableFile.renameTo(tableFile)){
+				return Messages.successMsg;
+			}
+		}
+
+		return Messages.failMsg;
+	}
+
+	public static ArrayList<String> tabsForCompare(String line){
+		ArrayList<String> results = new ArrayList<String>();
+
+		while (line.contains("\t")){
+			String temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			results.add(temp);
+		}
+		results.add(line);
+
+		return results;
+	}
+}
diff --git a/src/essgenes/ImgFileInfo.java b/src/essgenes/ImgFileInfo.java
new file mode 100644
index 0000000..d0bd1d3
--- /dev/null
+++ b/src/essgenes/ImgFileInfo.java
@@ -0,0 +1,12 @@
+package essgenes;
+
+public class ImgFileInfo {
+
+	String gene_oid;
+	String locus_tag;
+	String source;
+	String cluster_information;
+	String gene_information;
+	String e_value;
+	
+}
diff --git a/src/essgenes/Main.java b/src/essgenes/Main.java
new file mode 100644
index 0000000..fd3de00
--- /dev/null
+++ b/src/essgenes/Main.java
@@ -0,0 +1,48 @@
+/**
+ * 
+ */
+package essgenes;
+
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+import GUI.LegalDisclaimer;
+
+
+/**
+ * @author Sina Solaimanpour
+ *
+ */
+public class Main {
+
+	public static void main(String[] args) {
+		
+		try {
+			
+			String OSName = System.getProperty("os.name");
+
+			if(OSName.contains("Windows") || OSName.contains("windows")){
+				UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+			}else{
+				UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
+			}
+		} 
+		catch (UnsupportedLookAndFeelException e) {
+			
+		}
+		catch (ClassNotFoundException e) {
+			// handle exception
+		}
+		catch (InstantiationException e) {
+			// handle exception
+		}
+		catch (IllegalAccessException e) {
+			// handle exception
+		}
+		
+		LegalDisclaimer ld = new LegalDisclaimer();
+		ld.setVisible(true);
+		
+	}
+
+}
diff --git a/src/essgenes/Messages.java b/src/essgenes/Messages.java
new file mode 100644
index 0000000..9d412c9
--- /dev/null
+++ b/src/essgenes/Messages.java
@@ -0,0 +1,15 @@
+package essgenes;
+
+public class Messages {
+
+	public final static String successMsg = "Success";
+	public final static String failMsg = "Fail"; 
+	
+	// Workspace related strings
+	public final static String separatorString = "\t###\t";
+	public final static String projectName = "Name: ";
+	public final static String projectPath = "Path: ";
+	public final static String projectLibrariesCount = "Number_of_Libraries: ";
+	public final static String projectSequenceLen = "SequenceLen: ";
+	
+}
diff --git a/src/essgenes/MyFileUtil.java b/src/essgenes/MyFileUtil.java
new file mode 100644
index 0000000..94cdcc2
--- /dev/null
+++ b/src/essgenes/MyFileUtil.java
@@ -0,0 +1,86 @@
+package essgenes;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.ArrayList;
+
+public class MyFileUtil {
+
+	public static String tail( File file ) {
+		RandomAccessFile fileHandler = null;
+		try {
+			fileHandler = new RandomAccessFile( file, "r" );
+			long fileLength = fileHandler.length() - 1;
+			StringBuilder sb = new StringBuilder();
+
+			for(long filePointer = fileLength; filePointer != -1; filePointer--){
+				fileHandler.seek( filePointer );
+				int readByte = fileHandler.readByte();
+
+				if( readByte == 0xA ) {
+					if( filePointer == fileLength ) {
+						continue;
+					} else {
+						break;
+					}
+				} else if( readByte == 0xD ) {
+					if( filePointer == fileLength - 1 ) {
+						continue;
+					} else {
+						break;
+					}
+				}
+
+				sb.append( ( char ) readByte );
+			}
+
+			String lastLine = sb.reverse().toString();
+			return lastLine;
+		} catch( java.io.FileNotFoundException e ) {
+			e.printStackTrace();
+			return null;
+		} catch( java.io.IOException e ) {
+			e.printStackTrace();
+			return null;
+		} finally {
+			if (fileHandler != null )
+				try {
+					fileHandler.close();
+				} catch (IOException e) {
+					/* ignore */
+				}
+		}
+	}
+
+	public static ArrayList<String> tailNLines(File file, int linesCount) throws FileNotFoundException, IOException{
+		RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
+
+		ArrayList<String> result = new ArrayList<String>();
+
+		int lines = 0;
+		StringBuilder builder = new StringBuilder();
+		long length = file.length();
+		length--;        
+		randomAccessFile.seek(length);
+		for(long seek = length; seek >= 0; --seek){
+			randomAccessFile.seek(seek);
+			char c = (char)randomAccessFile.read();
+			builder.append(c);
+			if(c == '\n'){
+				builder = builder.reverse();
+				result.add(builder.toString());
+				lines++;
+				builder = null;
+				builder = new StringBuilder();
+				if (lines == linesCount){
+					break;
+				}
+			}
+		}
+		randomAccessFile.close();
+		return result;
+	}
+
+}
\ No newline at end of file
diff --git a/src/essgenes/PlotData.java b/src/essgenes/PlotData.java
new file mode 100644
index 0000000..d1bbe26
--- /dev/null
+++ b/src/essgenes/PlotData.java
@@ -0,0 +1,592 @@
+package essgenes;
+
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Random;
+import java.util.Vector;
+
+import javax.swing.JOptionPane;
+
+import org.apache.log4j.Logger;
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.LogAxis;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
+import org.jfree.data.xy.XYDataset;
+import org.jfree.data.xy.XYSeries;
+import org.jfree.data.xy.XYSeriesCollection;
+import org.jfree.util.ShapeUtilities;
+
+import CustomGUIComponent.MyXYDataItem;
+
+public class PlotData {
+
+	private static Logger logger = Logger.getLogger(PlotData.class.getName());
+
+	public static JFreeChart plotInsertionDensities(File table, String columnName, int columnIndex, String title, int averageNumOfGenesInBuckets, ProjectInfo info) throws IOException{
+
+		double trimPercent = 5;
+
+		BufferedReader br = new BufferedReader(new FileReader(table));
+
+		for (int i = 0; i < 5; i++){
+			br.readLine();
+		}
+
+		ArrayList<Double> densities = new ArrayList<Double>();
+
+		String line = br.readLine();
+		while (line != null){
+			String[] splitted = line.split("\t");
+			if (splitted[columnIndex].compareTo("NaN") == 0){
+				densities.add(0.0);
+			}else{
+				densities.add(Double.parseDouble(splitted[columnIndex]));
+			}
+			line = br.readLine();
+		}
+		br.close();
+
+		Collections.sort(densities);
+
+		double minAfterTrim = densities.get((int) (densities.size() * trimPercent / 100.0));
+		double maxAfterTrim = densities.get(densities.size() - (int) (densities.size() * trimPercent / 100.0));
+
+		double bucketSize = (maxAfterTrim - minAfterTrim);
+		bucketSize /= (densities.size() - (int) (2 * densities.size() * trimPercent / 100.0));
+		bucketSize *= averageNumOfGenesInBuckets;
+
+		ArrayList<Integer> counts = new ArrayList<Integer>();
+		ArrayList<Double> bucketStart = new ArrayList<Double>();
+
+		double temp = 0;
+		while(temp <= densities.get(densities.size() - 1)){
+			bucketStart.add(temp);
+			counts.add(0);
+
+			temp += bucketSize;
+		}
+
+		for (Double density : densities){
+			counts.set((int) (density / bucketSize), counts.get((int) (density / bucketSize)) + 1);
+		}
+
+		XYSeries series = new XYSeries("data");
+
+		for (int i = 0; i < counts.size(); i++){
+			series.add(bucketStart.get(i), counts.get(i));
+		}
+
+		XYSeriesCollection dataset = new XYSeriesCollection(series);
+
+
+		/*JFreeChart chart = ChartFactory.createXYBarChart(
+				title,
+				"Number of sequence reads", 
+				false,
+				"Number of unique insertions with the given number of reads", 
+				dataset,
+				PlotOrientation.VERTICAL,
+				true,
+				true,
+				false
+				);*/
+
+		final JFreeChart chart = ChartFactory.createXYLineChart(
+				title,																// chart title
+				"Insertion density per bp",											// x axis label
+				"Number of genes with the given insertion density",		// y axis label
+				dataset,															// data
+				PlotOrientation.VERTICAL,											// orientation
+				false,																// include legend
+				true,																// tooltips
+				false																// urls
+				);
+
+
+		XYPlot plot = (XYPlot) chart.getPlot();
+//		plot.getDomainAxis().setLowerBound(-10);
+		plot.setDomainGridlinesVisible(false);
+		plot.setRangeGridlinesVisible(false);
+
+		return chart;
+	}
+
+	public static JFreeChart anotherPlot(String libName, String title, ProjectInfo info, boolean onlyUniqueInsertions){
+
+		File input = new File(info.getPath() + libName + ".inspous");
+		ArrayList<Integer> counts_Y = new ArrayList<Integer>();
+		ArrayList<Integer> positions_X = new ArrayList<Integer>();
+
+		try {
+			BufferedReader br = new BufferedReader(new FileReader(input));
+
+			String line = br.readLine();
+
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			int numberOfReads = Integer.parseInt(line);
+
+			for (int i = 0; i < numberOfReads + 1; i++){
+				counts_Y.add(0);
+				positions_X.add(i);
+			}
+
+			while (line != null){
+				counts_Y.set(numberOfReads, counts_Y.get(numberOfReads) + 1);
+
+				line = br.readLine();
+
+				if (line != null){
+					line = line.substring(line.indexOf("\t") + 1);
+					line = line.substring(line.indexOf("\t") + 1);
+					numberOfReads = Integer.parseInt(line);
+				}
+			}
+			
+			br.close();
+
+		} catch (IOException e) {
+			logger.error(e.getStackTrace());
+		}
+
+		XYSeries series = new XYSeries("data");
+
+		for (int i = 0; i < positions_X.size(); i++){
+			if (positions_X.get(i) < 100 && counts_Y.get(i) == 0){
+				continue;
+			}
+			series.add(positions_X.get(i), counts_Y.get(i));
+		}
+
+		XYSeriesCollection dataset = new XYSeriesCollection(series);
+
+
+		/*JFreeChart chart = ChartFactory.createXYBarChart(
+				title,
+				"Number of sequence reads", 
+				false,
+				"Number of unique insertions with the given number of reads", 
+				dataset,
+				PlotOrientation.VERTICAL,
+				true,
+				true,
+				false
+				);*/
+
+		final JFreeChart chart = ChartFactory.createXYLineChart(
+				title,																// chart title
+				"Number of sequence reads",											// x axis label
+				"Number of unique insertions with the given number of reads",		// y axis label
+				dataset,															// data
+				PlotOrientation.VERTICAL,											// orientation
+				false,																// include legend
+				true,																// tooltips
+				false																// urls
+				);
+
+
+		XYPlot plot = (XYPlot) chart.getPlot();
+		plot.getDomainAxis().setLowerBound(0);
+		plot.setDomainGridlinesVisible(false);
+		plot.setRangeGridlinesVisible(false);
+
+		try {
+			saveToXls(positions_X, counts_Y, info, libName);
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+		}
+
+		return chart;
+	}
+
+	public static JFreeChart plotData(String libName, int windowLen, int windowStep, String title, ProjectInfo info, boolean onlyUniqueInsertions){
+
+		BufferedReader br = null;
+		String line = "";
+		Vector<Integer> numberOfInsertions = new Vector<Integer>();
+		Vector<Integer> positions = new Vector<Integer>();
+
+		try{
+
+			br = new BufferedReader(new FileReader(info.getPath() + libName + ".inspou"));
+
+			line = br.readLine();
+			while(line != null){
+				String tempLine = new String(line);
+				int tempPos = Integer.parseInt(tempLine.substring(0, tempLine.indexOf("\t")));
+				tempLine = tempLine.substring(tempLine.indexOf("\t") + 1);
+				int tempNumOfIns = Integer.parseInt(tempLine.substring(tempLine.indexOf("\t") + 1));
+
+				positions.add(tempPos);
+				numberOfInsertions.add(tempNumOfIns);
+
+				line = br.readLine();
+			}
+
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return null;
+		}finally{
+			try{
+				br.close();
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return null;
+			}
+		}
+
+		Vector<Integer> insertions = new Vector<Integer>();
+		int maxInsertions = 0;
+		int currentPosition = 0;
+
+		while(currentPosition < positions.get(positions.size() - 1)){
+			int tempCount = 0;
+
+			for (int i = 0; i < numberOfInsertions.size(); i++){
+				int tempPos = positions.get(i);
+				if(tempPos >= currentPosition && tempPos < currentPosition + windowLen){
+					if (onlyUniqueInsertions)
+						tempCount++;
+					else
+						tempCount += numberOfInsertions.get(i);
+				}
+
+				if(tempPos > currentPosition + windowLen){
+					break;
+				}
+			}
+
+			insertions.add(tempCount);
+			if(tempCount > maxInsertions){
+				maxInsertions = tempCount;
+			}
+
+			currentPosition += windowStep; 
+		}
+
+		Vector<Integer> xAxis = new Vector<Integer>();
+		Vector<Integer> yAxis = new Vector<Integer>();
+
+		for (int i = 0; i < maxInsertions + 1; i++){
+			yAxis.addElement(0);
+		}
+
+		for(int i = 0; i < insertions.size(); i++){
+			yAxis.setElementAt(yAxis.get(insertions.get(i)) + 1, insertions.get(i));
+		}
+
+		for(int i = 0; i < yAxis.size(); i++){
+			xAxis.add(i);
+		}
+
+		Double exponentialFitness = StatisticsHelper.exponentialLeastSquareFitting(xAxis, yAxis);
+		title = title + "\n" + "Exponential Regression, R2 = " + exponentialFitness;
+
+		XYDataset dataset = createDataset(xAxis, yAxis);
+		JFreeChart chart = createChart(dataset, title, !onlyUniqueInsertions, null, null, null, null);
+
+		try {
+			saveToXls(xAxis, yAxis, info, libName, windowLen, windowStep, onlyUniqueInsertions);
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+		}
+
+		return chart;
+	}
+
+	private static void saveToXls(ArrayList<Integer> xAxis, ArrayList<Integer> yAxis, ProjectInfo info, String libName) throws IOException{
+		String fileName = libName + " (DORPUI)";
+		String xlsPath = info.getPath() + fileName + ".xls";
+
+		File xlsFile = new File(xlsPath);
+		BufferedWriter bw = new BufferedWriter(new FileWriter(xlsFile));
+
+		bw.write(String.format("%s\t%s\n", "Number of sequence reads", "Number of unique insertions with the given number of reads"));
+
+		for(int i = 0; i < xAxis.size(); i++){
+			bw.write(String.format("%d\t%d\n", xAxis.get(i), yAxis.get(i)));
+		}
+
+		bw.close();
+
+		String msg = String.format("An Excel file containg all the data for this chart has been created at this location: %s", xlsPath);
+		JOptionPane.showMessageDialog(null, msg);
+
+	}
+
+	private static void saveToXls(Vector<Integer> xAxis, Vector<Integer> yAxis, ProjectInfo info, String libName, int len, int step, boolean unique) throws IOException{
+
+		String fileName = libName + "_w" + len + "_s" + step;
+		String xlsPath = "";
+
+		if (unique)
+			xlsPath = info.getPath() + fileName + " - Unique Insertions.xls";
+		else
+			xlsPath = info.getPath() + fileName + " - All Reads.xls";
+		File xlsFile = new File(xlsPath);
+
+		BufferedWriter bw = new BufferedWriter(new FileWriter(xlsFile));
+
+		bw.write(String.format("%s\t%s\n", "Number of insertions within a window", "Number of windows with the given number of insertions"));
+
+		for(int i = 0; i < xAxis.size(); i++){
+			bw.write(String.format("%d\t%d\n", xAxis.get(i), yAxis.get(i)));
+		}
+
+		bw.close();
+
+		String msg = String.format("An Excel file containg all the data for this chart has been created at this location: %s", xlsPath);
+		JOptionPane.showMessageDialog(null, msg);
+
+	}
+
+	private static XYDataset createDataset(Vector<Integer> xAxis, Vector<Integer> yAxis){
+		XYSeries series = new XYSeries("Plot");
+
+		for(int i = 0; i < xAxis.size(); i++){
+			series.add(xAxis.get(i), yAxis.get(i));
+		}
+
+		XYSeriesCollection dataset = new XYSeriesCollection();
+		dataset.addSeries(series);
+
+		return dataset;
+	}
+
+	private static JFreeChart createChart(XYDataset dataset, String title, boolean ifReads, Double xStart, Double xEnd, Double yStart, Double yEnd){
+
+		String xLabel;
+		String yLabel;
+		if (ifReads){
+			xLabel = "Number of reads within a window";
+			yLabel = "Number of windows with the given number of reads";
+		}else{
+			xLabel = "Number of insertions within a window";
+			yLabel = "Number of windows with the given number of insertions";			
+		}
+
+		//		create the chart...
+		final JFreeChart chart = ChartFactory.createXYLineChart(
+				title,      // chart title
+				xLabel,                      // x axis label
+				yLabel,                      // y axis label
+				dataset,                  // data
+				PlotOrientation.VERTICAL,
+				false,                     // include legend
+				true,                     // tooltips
+				false                     // urls
+				);
+
+		//		NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
+		chart.setBackgroundPaint(Color.white);
+
+		//      final StandardLegend legend = (StandardLegend) chart.getLegend();
+		//      legend.setDisplaySeriesShapes(true);
+
+		//		get a reference to the plot for further customization...
+		final XYPlot plot = chart.getXYPlot();
+		plot.setBackgroundPaint(Color.lightGray);
+		//		plot.setAxisOffset(new Spacer(Spacer.ABSOLUTE, 5.0, 5.0, 5.0, 5.0));
+		plot.setDomainGridlinePaint(Color.white);
+		plot.setRangeGridlinePaint(Color.white);
+
+		if (xStart != null && xEnd != null){
+			NumberAxis domain = (NumberAxis)plot.getDomainAxis();
+			domain.setRange(xStart, xEnd);
+		}
+
+		if (yStart != null && yEnd != null){
+			NumberAxis range = (NumberAxis)plot.getRangeAxis();
+			range.setRange(yStart, yEnd);
+		}
+
+		final XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
+		renderer.setSeriesLinesVisible(0, true);
+		renderer.setSeriesShapesVisible(0, false);
+		renderer.setSeriesStroke(0, new BasicStroke(5.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
+		//renderer.setSeriesShapesVisible(1, false);
+		plot.setRenderer(renderer);
+
+		//		change the auto tick unit selection to integer units only...
+		final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
+		rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
+		//		OPTIONAL CUSTOMISATION COMPLETED.
+
+		return chart;
+
+	}
+
+	public static JFreeChart plotColumns(String tableName, int firstCol, int secondCol, boolean logPlot, String title, boolean randomize, ProjectInfo info) throws IOException{
+
+		File tableFile = new File(info.getPath() + tableName + ".table.xls"); //REPLACE
+		BufferedReader br = new BufferedReader(new FileReader(tableFile));
+
+		String xAxisName = "Column " + firstCol + " (";
+		String yAxisName = "Column " + secondCol + " (";
+
+		String line = br.readLine();
+		ArrayList<String> tabs = AddColumns.tabsForCompare(line);
+		if (tabs.get(firstCol + 7) != null && tabs.get(firstCol + 7).compareTo("") != 0){
+			xAxisName = xAxisName + tabs.get(firstCol + 7) + ", "; 
+		}
+
+		if (tabs.get(secondCol + 7) != null && tabs.get(secondCol + 7).compareTo("") != 0){
+			yAxisName = yAxisName + tabs.get(secondCol + 7) + ", ";
+		}
+
+		line = br.readLine();
+		tabs = AddColumns.tabsForCompare(line);
+		if (tabs.get(firstCol + 7) != null && tabs.get(firstCol + 7).compareTo("") != 0){
+			xAxisName = xAxisName + tabs.get(firstCol + 7) + ", "; 
+		}
+
+		if (tabs.get(secondCol + 7) != null && tabs.get(secondCol + 7).compareTo("") != 0){
+			yAxisName = yAxisName + tabs.get(secondCol + 7) + ", ";
+		}
+
+		line = br.readLine();
+		tabs = AddColumns.tabsForCompare(line);
+		if (tabs.get(firstCol + 7) != null && tabs.get(firstCol + 7).compareTo("") != 0){
+			xAxisName = xAxisName + tabs.get(firstCol + 7) + ", "; 
+		}
+
+		if (tabs.get(secondCol + 7) != null && tabs.get(secondCol + 7).compareTo("") != 0){
+			yAxisName = yAxisName + tabs.get(secondCol + 7) + ", ";
+		}
+
+		line = br.readLine();
+		tabs = AddColumns.tabsForCompare(line);
+		if (tabs.get(firstCol + 7) != null && tabs.get(firstCol + 7).compareTo("") != 0){
+			xAxisName = xAxisName + tabs.get(firstCol + 7) + ", "; 
+		}
+
+		if (tabs.get(secondCol + 7) != null && tabs.get(secondCol + 7).compareTo("") != 0){
+			yAxisName = yAxisName + tabs.get(secondCol + 7) + ", ";
+		}
+
+		line = br.readLine();
+		tabs = AddColumns.tabsForCompare(line);
+		if (tabs.get(firstCol + 7) != null && tabs.get(firstCol + 7).compareTo("") != 0){
+			xAxisName = xAxisName + tabs.get(firstCol + 7) + ")"; 
+		}
+
+		if (tabs.get(secondCol + 7) != null && tabs.get(secondCol + 7).compareTo("") != 0){
+			yAxisName = yAxisName + tabs.get(secondCol + 7) + ")";
+		}
+
+		ArrayList<Double> xAxis = new ArrayList<Double>();
+		ArrayList<Double> yAxis = new ArrayList<Double>();
+
+		//Reading Main Data and Process it
+		line = br.readLine();
+		ArrayList<String> geneInfo = new ArrayList<String>();
+		while(line != null){
+			tabs = AddColumns.tabsForCompare(line);
+
+			double xTemp = Double.parseDouble(tabs.get(firstCol + 7));
+			double yTemp = Double.parseDouble(tabs.get(secondCol + 7));
+
+			/*String temp = "(X, Y) = (%f, %f),  locus_tag = %s,  gene_symbol = %s,  description = %s";
+			temp = String.format(temp, xTemp, yTemp, tabs.get(5), tabs.get(6), tabs.get(7));*/
+			String temp = "Info: locus_tag = %s,  gene_symbol = %s,  description = %s";
+			temp = String.format(temp, tabs.get(5), tabs.get(6), tabs.get(7));
+			
+			geneInfo.add(temp);
+			
+			xAxis.add(xTemp);
+			yAxis.add(yTemp);
+
+			line = br.readLine();
+		}
+
+		br.close();
+
+		if (randomize){
+			double lower = -0.25;
+			double higher = 0.25;
+			double constant = 1.0;
+			double D = higher - lower;
+
+			for (int i = 0; i < xAxis.size(); i++){
+				double rand = (new Random()).nextDouble();
+				double N = xAxis.get(i);
+				N += (constant + rand * D + lower);
+				xAxis.set(i, N);
+			}
+
+			for (int i = 0; i < yAxis.size(); i++){
+				double rand = (new Random()).nextDouble();
+				double N = yAxis.get(i);
+				N += (constant + rand * D + lower);
+				yAxis.set(i, N);
+			}
+		}
+
+		XYDataset dataset = createDataset(xAxis, yAxis, geneInfo);
+		JFreeChart chart = createScatterChart(dataset, logPlot, xAxisName, yAxisName, title);
+
+		return chart;
+	}
+
+	private static XYDataset createDataset(ArrayList<Double> xAxis, ArrayList<Double> yAxis, ArrayList<String> geneInfo){
+		XYSeries series = new XYSeries("Plot");
+
+		for(int i = 0; i < xAxis.size(); i++){
+			series.add(new MyXYDataItem(xAxis.get(i), yAxis.get(i), geneInfo.get(i)));
+		}
+
+		XYSeriesCollection dataset = new XYSeriesCollection();
+		dataset.addSeries(series);
+
+		return dataset;
+	}
+	
+	private static JFreeChart createScatterChart(XYDataset dataset, boolean logPlot, String xName, String yName, String title) {
+		final JFreeChart chart = ChartFactory.createScatterPlot(
+				title,                  	// chart title
+				xName,                      	// x axis label
+				yName,                      	// y axis label
+				dataset,                	// data
+				PlotOrientation.VERTICAL,
+				false,                     	// include legend
+				true,                     	// Tool-tips
+				false                     	// URLs
+				);
+		XYPlot plot = (XYPlot) chart.getPlot();
+
+		if (logPlot){
+			final LogAxis logAxisX = new LogAxis(xName);
+			//logAxisX.setStandardTickUnits(LogAxis.createLogTickUnits(Locale.ENGLISH));
+			//logAxisX.setRange(Math.log(maxX), Math.log(minX));
+			plot.setDomainAxis(logAxisX);
+
+			final LogAxis logAxisY = new LogAxis(yName);
+			//logAxisY.setStandardTickUnits(LogAxis.createLogTickUnits(Locale.ENGLISH));
+			//logAxisY.setRange(Math.log(maxY), Math.log(minY));
+			plot.setRangeAxis(logAxisY);
+			plot.setDomainGridlinesVisible(false);
+			plot.setRangeGridlinesVisible(false);
+		}
+
+		XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
+		renderer.setSeriesLinesVisible(0, false);
+		renderer.setSeriesShape(0, ShapeUtilities.createDiamond(2), true);
+		plot.setDomainGridlinesVisible(false);
+		plot.setRangeGridlinesVisible(false);
+		plot.setRenderer(renderer);
+		return chart;
+	}
+
+}
diff --git a/src/essgenes/PrepareFiles.java b/src/essgenes/PrepareFiles.java
new file mode 100644
index 0000000..bb017a7
--- /dev/null
+++ b/src/essgenes/PrepareFiles.java
@@ -0,0 +1,899 @@
+package essgenes;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+import javax.swing.JComboBox;
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import org.apache.log4j.Logger;
+
+import com.google.code.externalsorting.ExternalSort;
+
+public class PrepareFiles {
+
+	private static Logger logger = Logger.getLogger(PrepareFiles.class.getName());
+
+	public static String maxNumberOfInsertions(String libName, int winLen, int step, int maxNumIns, boolean ifOnlyInsertions, ProjectInfo info) throws IOException{
+		
+		File lib = new File(info.getPath() + libName + ".inspou");
+		BufferedReader br = new BufferedReader(new FileReader(lib));
+		
+		ArrayList<Integer> positions = new ArrayList<Integer>();
+		ArrayList<Integer> numberOfReads = new ArrayList<Integer>();
+		String line = br.readLine();
+		while (line != null){
+			int temp = Integer.parseInt(line.substring(0, line.indexOf("\t")));
+			positions.add(temp);
+			line = line.substring(line.indexOf("\t") + 1);
+			line = line.substring(line.indexOf("\t") + 1);
+			numberOfReads.add(Integer.parseInt(line));
+			line = br.readLine();
+		}
+
+		ArrayList<Integer> starts = new ArrayList<Integer>();
+ 		for (int i = 0; i < positions.get(positions.size() - 1); i += step){
+			int count = 0;
+			int num = 0;
+			for (int j = 0; j < positions.size(); j++){
+				if (positions.get(j) < i){
+					continue;
+				}
+				if (positions.get(j) > (i + winLen)){
+					break;
+				}
+				if (ifOnlyInsertions){
+					count++;
+				}else{
+					count++;
+					num += numberOfReads.get(j); 
+				}
+			}
+			
+			if (ifOnlyInsertions){
+				if (count < maxNumIns){
+					starts.add(i);
+				}
+			}else{
+				if (num < maxNumIns){
+					starts.add(i);
+				}
+			}
+		}
+		
+		ArrayList<String> boundaries = new ArrayList<String>();
+		int count = 0;
+		for (int i = 0; i < starts.size(); i++){
+			count = 0;
+			for (int j = i + 1; j <= starts.size(); j++){
+				int start = 0;
+				int end = 0;
+				
+				if (j >= starts.size() || i + count >= starts.size()){
+					start = starts.get(i);
+					end = starts.get(i + count) + winLen;
+				}else{
+					if (starts.get(j) < starts.get(i + count) + winLen){
+						count++;
+						continue;
+					}
+					start = starts.get(i);
+					end = starts.get(i + count) + winLen;
+				}
+				
+				boundaries.add(start + ".." + end);
+				break;
+			}
+			i = i + count;
+		}
+
+		JOptionPane.showMessageDialog(null, "Windows are found. Choose a new file name to store the result.");
+		
+		Path currentRelativePath = Paths.get("");
+		String location = currentRelativePath.toAbsolutePath()
+				.toString();
+		JFileChooser fileChooser = new JFileChooser(location);
+		fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
+		fileChooser.setFileFilter(new FileNameExtensionFilter("Excel tab delimited file (.xls)", "xls"));
+		int result = fileChooser.showSaveDialog(null);
+		
+		if (result == JFileChooser.APPROVE_OPTION){
+			
+			File save = fileChooser.getSelectedFile();
+			if (!save.getAbsolutePath().contains(".xls")){
+				save = new File(save.getAbsoluteFile() + ".xls");
+			}
+			BufferedWriter bw = new BufferedWriter(new FileWriter(save));
+			
+			if (ifOnlyInsertions){
+				bw.write(String.format("List of chomosomal segments with no more than %d insertions per %d bp window:\n", maxNumIns, winLen));
+			}else{
+				bw.write(String.format("List of chomosomal segments with no more than %d reads per %d bp window:\n", maxNumIns, winLen));
+			}
+			
+			for (int i = 0; i < boundaries.size(); i++){
+				bw.write(boundaries.get(i) + "\n");
+			}
+			
+			bw.close();
+			
+			br.close();
+			return save.getAbsolutePath();
+		}else{
+			br.close();
+			return Messages.failMsg; 
+		}		
+	}
+	
+	public static void processSelectedScaffold(String imgFilePath, String scaffoldName, ProjectInfo info) throws IOException{
+		
+		File genesFile = new File(info.getPath() + scaffoldName + ".genes");	
+		BufferedWriter bw = new BufferedWriter(new FileWriter(genesFile));
+		
+		bw.write("\t\t\t\t\t\t\t\n");
+		bw.write("\t\t\t\t\t\t\t\n");
+		bw.write("\t\t\t\t\t\t\t\n");
+		bw.write("\t\t\t\t\t\t\t\n");
+		
+		String start_coord = "start_coord";
+		String end_coord = "end_coord";
+		String strand = "strand";
+		String length = "length";
+		String locus_type = "locus_type";
+		String locus_tag = "locus_tag";
+		String gene_symbol = "gene_symbol";
+		String description = "description";
+		
+		String toBeWritten = String.format("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", start_coord, end_coord, strand, length, locus_type, locus_tag, gene_symbol, description);
+		bw.write(toBeWritten);
+		
+		List<List<ImgFileInfo>> wholeImg = extractScaffolds(imgFilePath, info, null);
+		
+		for (List<ImgFileInfo> tempArray : wholeImg){
+			for (ImgFileInfo t : tempArray){
+				
+				if(t.source.compareTo("Locus_type") == 0){
+					locus_type = t.gene_information;
+				}
+				
+				if(t.source.compareTo("Gene_symbol") == 0){
+					gene_symbol = t.gene_information;
+				}
+					
+				if(t.source.compareTo("Coordinates") == 0){
+					String temp = t.gene_information;
+					start_coord = temp.substring(0, temp.indexOf(".."));
+					temp = temp.substring(temp.indexOf("..") + 2);
+					
+					end_coord = temp.substring(0, temp.indexOf("("));
+					
+					strand = temp.charAt(temp.indexOf("(") + 1) + "";
+					
+					length = (Integer.parseInt(end_coord) - Integer.parseInt(start_coord) + 1) + "";
+				}
+				
+				if(t.source.compareTo("Product_name") == 0){
+					description = t.gene_information;
+				}
+				
+				locus_tag = t.locus_tag;
+			}
+			toBeWritten = String.format("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", start_coord, end_coord, strand, length, locus_type, locus_tag, gene_symbol, description);
+			bw.write(toBeWritten);
+			bw.flush();
+		}
+		
+		if (Integer.parseInt(end_coord) > info.getSequenceLen()){
+
+			JOptionPane.showMessageDialog(null, ""
+					+ "ERROR: Genes were found at positions above the sequence length. The project was not created.\n"
+					+ "\n"
+					+ "Possible reasons and solutions:\n"
+					+ "- The sequence length provided is incorrect. Correct the sequence length and try again.\n"
+					+ "- You are using a wrong file with annotation or the file is in a wrong format. Verify that you are\n"
+					+ "  the right file and that it is in the appropriate format.\n"
+					+ "- This error can also occur if you did not push 'apply' to enter the sequence length prior to continuing"
+					, "ERROR", JOptionPane.ERROR_MESSAGE);
+
+			bw.close();
+			
+			deleteAllOtherGenesFiles("", info);
+			info.setGeneFile(null);
+			return;
+		}
+		
+		bw.close();
+		
+		deleteAllOtherGenesFiles(genesFile.getName(), info);
+		
+		info.setGeneFile(genesFile);
+	}
+	
+	public static void deleteAllOtherGenesFiles(String notToBeDeleted, ProjectInfo info){
+		File projectDir = new File(info.getPath());
+		File[] match = projectDir.listFiles(new FilenameFilter() {
+			
+			@Override
+			public boolean accept(File dir, String name) {
+				return (name.endsWith(".genes") || name.endsWith(".Genes"));
+			}
+		});
+		
+		for (File t : match){
+			if (t.getName().compareTo(notToBeDeleted) != 0){
+				t.delete();
+			}
+		}
+		
+	}
+	
+	public static List<List<ImgFileInfo>> extractScaffolds(String path, ProjectInfo info, JComboBox<String> enableAfterDone) throws IOException{
+		File imgFile = new File(path);
+		
+		BufferedReader br = new BufferedReader(new FileReader(imgFile));
+		br.readLine();
+		
+		List<List<ImgFileInfo>> wholeImgFile = new ArrayList<List<ImgFileInfo>>();
+		List<ImgFileInfo> imgLines = new ArrayList<ImgFileInfo>();
+		String line = br.readLine();
+		while(line != null){
+			ImgFileInfo tempImgLine = new ImgFileInfo();
+			
+			if(line.compareTo("\t\t\t\t\t") == 0){
+				wholeImgFile.add(imgLines);
+				imgLines = new ArrayList<ImgFileInfo>();
+				line = br.readLine();
+				continue;
+			}
+			
+			String temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			tempImgLine.gene_oid = temp;
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			tempImgLine.locus_tag = temp;
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			tempImgLine.source = temp;
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			tempImgLine.cluster_information = temp;
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+			tempImgLine.gene_information = temp;
+
+			tempImgLine.e_value = line;
+
+			imgLines.add(tempImgLine);
+			line = br.readLine();
+		}
+		
+		br.close();
+		
+		List<String> scaffolds = new ArrayList<String>();
+		for (List<ImgFileInfo> arrayTemp : wholeImgFile){
+			for (ImgFileInfo t : arrayTemp){
+				if (t.source.compareTo("Scaffold") == 0){
+					if (!scaffolds.contains(t.gene_information)){
+						scaffolds.add(t.gene_information);
+					}
+				}
+			}
+		}
+		
+		if(enableAfterDone != null){
+			enableAfterDone.removeAllItems();
+			for (String t : scaffolds){
+				enableAfterDone.addItem(t);
+			}
+			enableAfterDone.setEnabled(true);
+		}
+
+		return wholeImgFile;
+	}
+	
+	public static String createGeneFile(String pttFilePath, String rntFilePath, String projectPath, ProjectInfo info) {
+
+		String geneFileName = prepareFileName(pttFilePath, ".genes");
+		if (geneFileName.contains(".ptt")){
+			geneFileName = geneFileName.substring(0, geneFileName.length() - 10 ) + ".genes";
+		}
+		
+		File genesFile = new File(projectPath + geneFileName);
+		File pttFile = new File(pttFilePath);
+
+		BufferedWriter bw = null;
+		BufferedReader br = null;
+		try {
+			if(!genesFile.exists()){
+				genesFile.createNewFile();
+			}
+			bw = new BufferedWriter(new FileWriter(genesFile));
+			br = new BufferedReader(new FileReader(pttFile));
+			writeToGenesFile(bw, br, true);
+			br.close();
+			
+			if(rntFilePath != null && rntFilePath.compareTo("") != 0){
+				File rntFile = new File(rntFilePath);
+				br = new BufferedReader(new FileReader(rntFile));
+				writeToGenesFile(bw, br, false);
+				br.close();
+			}
+			
+			bw.close();
+			
+			//First Sort it
+			File sorted = new File("sorted.genes");
+			Comparator<String> comparator = new Comparator<String>() {
+
+				@Override
+				public int compare(String arg0, String arg1) {
+					String start0 = arg0.substring(0, arg0.indexOf("\t"));
+					String start1 = arg1.substring(0, arg1.indexOf("\t"));
+					
+					Integer int0 = Integer.parseInt(start0);
+					Integer int1 = Integer.parseInt(start1);
+					
+					return int0.compareTo(int1);
+				}
+			};
+			sortNotDistinct(genesFile.getAbsolutePath(), sorted.getAbsolutePath(), comparator);
+			
+			if(genesFile.delete()){
+				if(!sorted.renameTo(genesFile)){
+					logger.fatal("Not renamed!!!");
+				}
+			}else{
+				JOptionPane.showMessageDialog(null, "The old genes file is in use, please close the file and try again!");
+				return Messages.failMsg;
+			}
+			
+			//Then Write the Header to the File
+			writeGenesFileHeader(genesFile);
+			
+			ArrayList<String> lines = MyFileUtil.tailNLines(genesFile, 2);
+			String temp = lines.get(1);
+			temp = temp.substring(temp.indexOf("\t") + 1);
+			temp = temp.substring(0, temp.indexOf("\t"));
+
+			if(Integer.parseInt(temp) > info.getSequenceLen()){
+				JOptionPane.showMessageDialog(null, ""
+						+ "ERROR: Genes were found at positions above the sequence length. The project was not created.\n"
+						+ "\n"
+						+ "Possible reasons and solutions:\n"
+						+ "- The sequence length provided is incorrect. Correct the sequence length and try again.\n"
+						+ "- You are using a wrong file with annotation or the file is in a wrong format. Verify that you are\n"
+						+ "  the right file and that it is in the appropriate format.\n"
+						+ "- This error can also occur if you did not push 'apply' to enter the sequence length prior to continuing"
+						, "ERROR", JOptionPane.ERROR_MESSAGE);
+				
+				if(!genesFile.delete()){
+					logger.warn("Could not delete the incompatible gene file!");
+				}
+				
+				return Messages.failMsg;
+			}
+			
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+			return Messages.failMsg;
+		} 
+
+		return genesFile.getAbsolutePath();
+	}
+
+	private static void writeGenesFileHeader(File genesFile){
+
+		BufferedReader br = null;
+		BufferedWriter bw = null;
+		
+		File tempFile = new File("temp.genes");
+		try {
+			br = new BufferedReader(new FileReader(genesFile));
+			bw = new BufferedWriter(new FileWriter(tempFile));
+
+			//Leaving 4 Lines Blank For Later Added Details
+			bw.write("\t\t\t\t\t\t\t\n");
+			bw.write("\t\t\t\t\t\t\t\n");
+			bw.write("\t\t\t\t\t\t\t\n");
+			bw.write("\t\t\t\t\t\t\t\n");
+
+			//Table Columns
+			String start_coord = "start_coord";
+			String end_coord = "end_coord";
+			String strand = "strand";
+			String length = "length";
+			String locus_type = "locus_type";
+			String locus_tag = "locus_tag";
+			String gene_symbol = "gene_symbol";
+			String description = "description";
+			String temp = "";
+
+			temp = String.format("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", start_coord, end_coord, strand, 
+					length, locus_type, locus_tag, gene_symbol, description);
+			bw.write(temp);
+			bw.flush();
+			
+			temp = br.readLine();
+			while(temp != null){
+				bw.write(temp + "\n");
+				bw.flush();
+				
+				temp = br.readLine();
+			}
+			
+			br.close();
+			bw.close();
+			
+			genesFile.delete();
+			tempFile.renameTo(genesFile);
+			
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+			return;
+		} finally {
+			try {
+				br.close();
+				bw.close();
+			} catch (IOException e) {
+				logger.error(e.getMessage());
+				return;
+			}
+		}
+		
+	}
+
+	private static void writeToGenesFile(BufferedWriter bw, BufferedReader br, boolean ptt) throws IOException{
+
+		//Skip File Headers
+		br.readLine();
+		br.readLine();
+		String line = br.readLine();
+
+		//Table Columns
+		String start_coord = "start_coord";
+		String end_coord = "end_coord";
+		String strand = "strand";
+		String length = "length";
+		String locus_type = "locus_type";
+		String locus_tag = "locus_tag";
+		String gene_symbol = "gene_symbol";
+		String description = "description";
+		String temp = "";
+
+		while(line != null){
+			line = br.readLine();
+			if(line == null)
+				break;
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+
+			start_coord = temp.substring(0, temp.indexOf(".."));
+			end_coord = temp.substring(temp.indexOf("..") + 2);
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+
+			strand = temp;
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+
+			length = temp;
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+
+			gene_symbol = temp;
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+
+			locus_tag = temp;
+
+			if(ptt){
+				locus_type = "CDS";
+			}else{
+				locus_type = "RNA";
+			}
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+
+			temp = line.substring(0, line.indexOf("\t"));
+			line = line.substring(line.indexOf("\t") + 1);
+
+			description = line;
+
+			temp = String.format("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", start_coord, end_coord, strand, 
+					length, locus_type, locus_tag, gene_symbol, description);
+			bw.write(temp);
+			bw.flush();
+		}
+
+	}
+
+	public static String countUniqueLocationsSortedByNumbers(String samFilePath, String outPath){
+
+		String inputPath = prepareOutputFilePath(samFilePath, outPath, ".inspou");
+		String outputPath = prepareOutputFilePath(samFilePath, outPath, ".inspous");
+
+		if ((new File(outputPath)).exists()){
+			outputPath = prepareOutputFilePath(samFilePath, outPath, "-temp.inspous");
+		}
+		
+		Comparator<String> comparator = new Comparator<String>() {
+			@Override
+			public int compare(String r1, String r2){
+				r1 = r1.substring(r1.indexOf("\t") + 3);
+				r2 = r2.substring(r2.indexOf("\t") + 3);
+
+				Integer num1 = Integer.parseInt(r1);
+				Integer num2 = Integer.parseInt(r2);
+
+				return num2.compareTo(num1);
+			}
+		};
+
+		try {
+			sortNotDistinct(inputPath, outputPath, comparator);
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+			return e.getMessage();
+		} catch(Exception e){
+			logger.error(e.getMessage());
+			return e.getMessage();
+		}
+
+		return Messages.successMsg;
+	}
+
+	public static String countUniqueLocations(String samFilePath, String outPath, Integer uniqueLimit){
+
+		String sortedPath = prepareOutputFilePath(samFilePath, outPath, ".inspos");
+		String uniquePath = prepareOutputFilePath(samFilePath, outPath, ".inspou");
+		String tempPath = prepareOutputFilePath(samFilePath, outPath, ".tmp");
+
+		if ((new File(uniquePath).exists())){
+			uniquePath = prepareOutputFilePath(samFilePath, outPath, "-temp.inspou");
+		}
+		
+		File input = new File(sortedPath);
+		File tempFile = new File(tempPath);
+
+		BufferedReader br = null;
+		BufferedWriter bw = null;
+
+		try{
+			br = new BufferedReader(new FileReader(input));
+			bw = new BufferedWriter(new FileWriter(tempPath));
+
+			String line = br.readLine();
+			int currentUniqueNumber = Integer.parseInt(line);
+			int count = 0;
+
+			while(line != null){
+				int current = Integer.parseInt(line);
+
+				if(current == currentUniqueNumber){
+					count++;
+				}else{
+					String sign = "+";
+					if(currentUniqueNumber < 0){
+						sign = "-";
+						currentUniqueNumber *= -1;
+					}
+
+					if (uniqueLimit != 0){
+						if (count > uniqueLimit){
+							bw.write(currentUniqueNumber + "\t" + sign + "\t" + count + "\n");
+						}
+					}else{
+						bw.write(currentUniqueNumber + "\t" + sign + "\t" + count + "\n");
+					}
+
+					currentUniqueNumber = current;
+					count = 1;
+				}
+
+				line = br.readLine();
+			}
+
+			String sign = "+";
+			if(currentUniqueNumber < 0){
+				sign = "-";
+				currentUniqueNumber *= -1;
+			}
+
+			if (uniqueLimit != 0){
+				if (count > uniqueLimit){
+					bw.write(currentUniqueNumber + "\t" + sign + "\t" + count + "\n");
+				}
+			}else{
+				bw.write(currentUniqueNumber + "\t" + sign + "\t" + count + "\n");
+			}
+				
+
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return e.getMessage();
+		} catch(Exception e){
+			logger.error(e.getMessage());
+			return e.getMessage();
+		}finally{
+			try{
+				br.close();
+				bw.close();
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return e.getMessage();
+			}
+		}
+
+		Comparator<String> comparator = new Comparator<String>() {
+			@Override
+			public int compare(String r1, String r2){
+				r1 = r1.substring(0, r1.indexOf("\t"));
+				r2 = r2.substring(0, r2.indexOf("\t"));
+
+				Integer num1 = Integer.parseInt(r1);
+				Integer num2 = Integer.parseInt(r2);
+
+				return num1.compareTo(num2);
+			}
+		};
+
+		try {
+			sortNotDistinct(tempPath, uniquePath, comparator);
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+			return e.getMessage();
+		} catch(Exception e){
+			logger.error(e.getMessage());
+			return e.getMessage();
+		}
+
+		tempFile.delete();
+
+		return Messages.successMsg;
+	}
+
+	public static String sortTheLocationsFile(String samFilePath, String outPath) {
+
+		String unsortedPath = prepareOutputFilePath(samFilePath, outPath, ".inspo");
+		String sortedPath = prepareOutputFilePath(samFilePath, outPath, ".inspos");
+
+		if ((new File(sortedPath).exists())){
+			sortedPath = prepareOutputFilePath(samFilePath, outPath, "-temp.inspos");
+		}
+		
+		try{
+			Comparator<String> comparator = new Comparator<String>() {
+				@Override
+				public int compare(String r1, String r2){
+					Integer num1 = Integer.parseInt(r1);
+					Integer num2 = Integer.parseInt(r2);
+
+					return num1.compareTo(num2);
+				}
+			};
+
+			sortNotDistinct(unsortedPath, sortedPath, comparator);
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return e.getMessage();
+		} catch(Exception e){
+			logger.error(e.getMessage());
+			return e.getMessage();
+		}
+
+		return Messages.successMsg;
+	}
+
+	private static void sortNotDistinct(String inputFile, String outputFile, Comparator<String> comparator) throws IOException{	
+		boolean verbose = false;
+		boolean distinct = false;
+		int maxTempFiles = 2048;
+		Charset cs = Charset.forName("US-ASCII");
+		File tempFileStore = null;
+		int headersize = 0;
+		boolean useGZip = false;
+
+		List<File> filesList = ExternalSort.sortInBatch(new File(inputFile), comparator, maxTempFiles, cs, tempFileStore, distinct, headersize, useGZip);
+		if(verbose) {
+			try{
+				logger.info("created " + filesList.size() + " tmp files");
+			}catch(Exception e){
+				e.printStackTrace();
+			}
+		}
+
+		ExternalSort.mergeSortedFiles(filesList, new File(outputFile), comparator, cs, distinct, false, useGZip);
+	}
+
+	public static String prepareFileName(String inPath, String extension){
+		int tempIndex = 0;
+		boolean windows = true;
+		if (inPath.contains("/")){
+			windows = false;
+		}
+
+		String fileName = new String(inPath);
+		if(fileName.endsWith(".inspo") || fileName.endsWith(".fastq")){
+			fileName = fileName.substring(0, fileName.length() - 6);
+		}else if(fileName.endsWith(".sam")){
+			fileName = fileName.substring(0, fileName.length() - 4);			
+		}
+		if (windows){
+			while(fileName.contains("\\")){
+				tempIndex = fileName.indexOf("\\");
+				fileName = fileName.substring(tempIndex + 1);
+			}
+		}else{
+			while(fileName.contains("/")){
+				tempIndex = fileName.indexOf("/");
+				fileName = fileName.substring(tempIndex + 1);
+			}
+		}
+
+		return fileName + extension;
+	}
+
+	public static String prepareOutputFilePath(String inPath, String outPath, String extension){
+		int tempIndex = 0;
+		boolean windows = true;
+		if (inPath.contains("/")){
+			windows = false;
+		}
+
+		String fileName = new String(inPath);
+		
+		if(fileName.endsWith(".inspo") || fileName.endsWith(".fastq")){
+			fileName = fileName.substring(0, fileName.length() - 6);
+		}else{
+			fileName = fileName.substring(0, fileName.length() - 4);			
+		}
+		if (windows){
+			while(fileName.contains("\\")){
+				tempIndex = fileName.indexOf("\\");
+				fileName = fileName.substring(tempIndex + 1);
+			}
+		}else{
+			while(fileName.contains("/")){
+				tempIndex = fileName.indexOf("/");
+				fileName = fileName.substring(tempIndex + 1);
+			}
+		}
+
+		return outPath + fileName + extension;
+	}
+
+	public static String findTheLocationsInTheSamFile(String inFilePath, String outPath, int CHRLEN){
+
+		String outFilePath = prepareOutputFilePath(inFilePath, outPath, ".inspo");
+
+		File input = new File(inFilePath);
+		File output = new File(outFilePath);
+		
+		if (output.exists()){
+			outFilePath = prepareOutputFilePath(inFilePath, outPath, "-temp.inspo");
+			output = new File(outFilePath);
+		}
+
+		BufferedReader br = null;
+		BufferedWriter bw = null;
+		try {
+			br = new BufferedReader(new FileReader(input));	        
+			bw = new BufferedWriter(new FileWriter(output));
+
+			//long totalSize = input.length();
+			//long readSize = 0;
+
+			String line = br.readLine();
+			
+			while (line.startsWith("@")){
+				line = br.readLine();
+			}
+
+			while(line != null){
+				line = line.substring(line.indexOf("\t") + 1);
+				int direction = Integer.parseInt(line.substring(0, line.indexOf("\t")));
+
+				if (direction == 0){
+					direction = 1;
+				}else if(direction == 16){
+					direction = -1;
+				}else{
+					logger.warn("There must have been a mistake. The direction code is --> " + direction);
+				}	
+
+				line = line.substring(line.indexOf("\t") + 1);
+				line = line.substring(line.indexOf("\t") + 1);
+
+				int location = 0;
+				if (direction == 1){
+					location = Integer.parseInt(line.substring(0, line.indexOf("\t")));
+				}else if (direction == -1){
+					location = (Integer.parseInt(line.substring(0, line.indexOf("\t"))) * -1) /*- 50*/;
+					
+					line = line.substring(line.indexOf("\t") + 1);
+					line = line.substring(line.indexOf("\t") + 1);
+
+					String pattern = line.substring(0, line.indexOf("\t"));
+					int sum = 0;
+					int tIndex = 0;
+					StringBuilder num = new StringBuilder();
+					String validChars = "MD=XN";
+					while (tIndex < pattern.length()){
+						if (pattern.charAt(tIndex) >= '0' && pattern.charAt(tIndex) <= '9'){
+							num.append(pattern.charAt(tIndex));
+						}else{
+							if (validChars.contains(pattern.charAt(tIndex) + "")){
+								sum += Integer.parseInt(num.toString());
+							}
+							num = new StringBuilder();
+						}
+						tIndex++;
+					}
+					
+					location -= sum;
+					
+					if (location < -CHRLEN){
+						location += CHRLEN;
+					}
+				}
+
+				if(direction == 1 || direction == -1){
+					bw.write(location + "\n");
+					bw.flush();
+				}
+
+				line = br.readLine();
+			}
+
+		} catch (FileNotFoundException e) {
+			logger.error(e.getMessage());
+			return e.getMessage();
+		} catch (IOException e) {
+			logger.error(e.getMessage());
+			return e.getMessage();
+		} catch(Exception e){
+			logger.error(e.getMessage());
+			return e.getMessage();
+		}finally {
+			try {
+				br.close();
+				bw.close();
+			} catch (IOException e) {
+				logger.error(e.getMessage());
+				return e.getMessage();
+			}
+		}
+
+		return Messages.successMsg;
+
+	}
+
+}
diff --git a/src/essgenes/ProjectInfo.java b/src/essgenes/ProjectInfo.java
new file mode 100644
index 0000000..27dc438
--- /dev/null
+++ b/src/essgenes/ProjectInfo.java
@@ -0,0 +1,47 @@
+package essgenes;
+
+import java.io.File;
+
+public class ProjectInfo {
+
+	private String name;
+	private String path;
+	private int sequenceLen;
+	private File geneFile;
+	private File projectFile;
+	
+	public void createFile(String path) {
+		projectFile = new File(path);
+	}
+	
+	public File getFile(){
+		return projectFile;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	public void setName(String name) {
+		this.name = name;
+	}
+	public String getPath() {
+		return path;
+	}
+	public void setPath(String path) {
+		this.path = path;
+	}
+	public int getSequenceLen() {
+		return sequenceLen;
+	}
+	public void setSequenceLen(int sequenceLen) {
+		this.sequenceLen = sequenceLen;
+	}
+
+	public File getGeneFile() {
+		return geneFile;
+	}
+
+	public void setGeneFile(File geneFile) {
+		this.geneFile = geneFile;
+	}
+}
diff --git a/src/essgenes/StatisticsHelper.java b/src/essgenes/StatisticsHelper.java
new file mode 100644
index 0000000..a9ecbd0
--- /dev/null
+++ b/src/essgenes/StatisticsHelper.java
@@ -0,0 +1,450 @@
+package essgenes;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.JFrame;
+
+import org.apache.commons.math3.stat.descriptive.moment.Mean;
+import org.apache.commons.math3.stat.descriptive.summary.Sum;
+import org.apache.commons.math3.util.Pair;
+import org.apache.log4j.Logger;
+
+import GUI.MainFrame;
+
+import com.google.common.primitives.Doubles;
+
+public class StatisticsHelper {
+	
+	private static Logger logger = Logger.getLogger(StatisticsHelper.class.getName());
+	
+	/**
+	 * Computes the best fitting power law distribution for the input x and y arrays.
+	 * This is done using the method explained here,
+	 * 		Weisstein, Eric W. "Least Squares Fitting--Power Law." From MathWorld--A Wolfram Web Resource. 
+	 * 		http://mathworld.wolfram.com/LeastSquaresFittingPowerLaw.html
+	 * 
+	 * @param x x values
+	 * @param y y values
+	 * @return The fitness of the input values compared to the best fitting power law distribution
+	 */
+	public static Double powerLawLeastSquareFitting(double[] x, double[] y){
+		Double fitness = 0.0;
+		
+		// Check data compatibility
+		if (!compabilityCheck(x, y)){
+			return 1.0;
+		}
+		
+		// If they are compatible, remove all zeros in both x and y arrays
+		Pair<double[], double[]> result = removeZeros(x, y);
+		x = result.getFirst();
+		y = result.getSecond();
+
+		// Temp Variables
+		Double t1 = 0.0;
+		Double t2 = 0.0;
+		Double t3 = 0.0;
+		Double t4 = 0.0;
+		Double t5 = 0.0;
+		Double N = (double) x.length;
+		
+		// First, calculate B
+		for (int i = 0; i < N; i++){
+			Double lnx = Math.log(x[i]);
+			Double lny = Math.log(y[i]);
+			
+			t1 += (lnx * lny);
+			t2 += (lnx);
+			t3 += (lny);
+			t4 += (Math.pow(lnx, 2));
+			t5 += (lnx);
+		}
+		
+		Double B = 0.0;
+		B = (N * t1 - t2 * t3) / (N * t4 - Math.pow(t5, 2));
+		
+		// Calculate A
+		Double A = Math.pow(Math.E, (t3 - B * t2) / (N));
+		
+		logger.debug("y = Ax^B \n\tA: " + A + "\n\tB: " + B);
+		
+		Double R2 = 0.0;
+		
+		for (int i = 0; i < N; i++){
+			Double temp = A * Math.pow(x[i], B);
+			R2 += (Math.pow(y[i] - temp, 2));
+		}
+		
+		fitness = 1 / R2;
+		
+		logger.debug("\tR2: " + R2);
+		logger.debug("\tFitness: " + fitness);
+		
+		return fitness;
+	}
+	
+	/**
+	 * Computes the best fitting exponential distribution for the input x and y arrays.
+	 * This is done using the method explained here,
+	 * 		Weisstein, Eric W. "Least Squares Fitting--Exponential." From MathWorld--A Wolfram Web Resource.
+	 * 		http://mathworld.wolfram.com/LeastSquaresFittingExponential.html
+	 * 
+	 * This method implements formulas (3) and (4) in the referenced webpage.
+	 * 
+	 * @param x x values
+	 * @param y y values
+	 * @return The fitness of the input values compared to the best fitting exponential distribution
+	 */
+	public static Double exponentialLeastSquareFitting(double[] x, double[] y){
+		// Check data compatibility
+		if (!compabilityCheck(x, y)){
+			return 1.0;
+		}
+
+		// If they are compatible, remove all zeros in both x and y arrays
+		Pair<double[], double[]> result = removeZeros(x, y);
+		x = result.getFirst();
+		y = result.getSecond();
+		
+		// Temp Variables
+		Double t1 = 0.0;
+		Double t2 = 0.0;
+		Double t3 = 0.0;
+		Double t4 = 0.0;
+		Double t5 = 0.0;
+		Double t6 = 0.0;
+		Double t7 = 0.0;
+		Double N = (double) x.length;
+		
+		for (int i = 0; i < N; i++){
+			Double lny = Math.log(y[i]);
+			
+			t1 += (Math.pow(x[i], 2) * y[i]);
+			t2 += (y[i] * lny);
+			t3 += (x[i] * y[i]);
+			t4 += (x[i] * y[i] * lny);
+			t5 += (y[i]);
+			t6 += (Math.pow(x[i], 2) * y[i]);
+			t7 += (x[i] * y[i]);
+		}
+		
+		Double A = Math.exp((t1 * t2 - t3 * t4) / (t5 * t6 - Math.pow(t7, 2)));
+		Double B = (t5 * t4 - t3 * t2) / (t5 * t6 - Math.pow(t7, 2));
+		
+		logger.debug("y = A e ^ Bx");
+		logger.debug("\tA: " + A);
+		logger.debug("\tB: " + B);
+
+		Double mean = (new Mean()).evaluate(y);
+		Double SStot = 0.0;
+		Double SSres = 0.0;
+		Double R2 = 0.0;
+		
+		for (int i = 0; i < N; i++){
+			Double f = A * Math.exp(B * x[i]);
+			SStot += Math.pow(y[i] - mean, 2);
+			SSres += Math.pow(y[i] - f, 2);
+		}
+		
+		R2 = 1 - SSres / SStot;
+		
+		logger.debug("\tR2: " + R2);
+		
+		return R2;
+	}
+	
+	public static Double exponentialLeastSquareFitting(List<Integer> x, List<Integer> y){
+		return exponentialLeastSquareFitting(Doubles.toArray(x), Doubles.toArray(y));
+	}
+		
+	private static Pair<double[], double[]> removeZeros(double[] x, double[] y) {
+		List<Double> tempX = new ArrayList<Double>();
+		List<Double> tempY = new ArrayList<Double>();
+		
+		for (int i = 0; i < x.length; i++){
+			if (x[i] == 0){
+				continue;
+			}else if(y[i] == 0){
+				break;
+				/*tempX.add(x[i]);
+				tempY.add(0.2);*/
+			}else{
+				tempX.add(x[i]);
+				tempY.add(y[i]);
+			}
+		}
+		
+		return new Pair<double[], double[]>(Doubles.toArray(tempX), Doubles.toArray(tempY));
+	}
+
+	private static boolean compabilityCheck(double[] x, double[] y) {
+		if (x.length != y.length){
+			return false;
+		}
+		
+		/*int zeroCount = 0;
+		for (int i = 0; i < x.length; i++){
+			if (x[i] == 0 || y[i] == 0){
+				zeroCount++;
+			}
+		}*/
+		
+		/*if (((double)zeroCount / x.length) > 0.2){
+			return false;
+		}*/
+		
+		return true;
+	}
+
+	public static Double powerLawLeastSquareFitting(List<Integer> x, List<Integer> y){
+		return powerLawLeastSquareFitting(Doubles.toArray(x), Doubles.toArray(y));
+	}
+	
+	public static Double bimodalityCoefficient(double[] sample){
+		Double b = 0.0;
+		
+		Double g = sampleSkewness(sample);
+		Double k = sampleExcessKurtosis(sample);
+		
+		Double temp = (3 * Math.pow(sample.length - 1, 2)) / ((sample.length - 2) * (sample.length - 3));
+		b = (Math.pow(g, 2) + 1) / (k + temp);
+		
+		return b;
+	}
+	
+	public static Double bimodalityCoefficient(List<Integer> sample){
+		return bimodalityCoefficient(Doubles.toArray(sample));
+	}
+	
+	public static Double sampleExcessKurtosis(double[] sample){
+		Double g = 0.0;
+		
+		Double mean = mean(sample);
+		
+		Double m4 = 0.0;
+		Double m2 = 0.0;
+		for (Double d : sample){
+			m4 += Math.pow(d - mean, 4);
+			m2 += Math.pow(d - mean, 2);
+		}
+		m4 *= (1.0 / sample.length);
+		m2 *= (1.0 / sample.length);
+		m2 = Math.pow(m2, 2);
+		
+		g = (m4 / m2) - 3;
+		
+		return g;
+	}
+	
+	public static Double sampleExcessKurtosis(List<Integer> sample){
+		return sampleExcessKurtosis(Doubles.toArray(sample));
+	}
+	
+	public static Double sampleSkewness(double[] sample){
+		Double g = 0.0;
+		Double mean = mean(sample);
+		
+		Double m3 = 0.0;
+		Double m2 = 0.0;
+		for (Double d : sample){
+			m3 += Math.pow(d - mean, 3);
+			m2 += Math.pow(d - mean, 2);
+		}
+		m3 *= (1.0 / sample.length);
+		m2 *= (1.0 / sample.length);
+		m2 = Math.pow(m2, (3.0 / 2.0));
+		
+		g = m3 / m2;
+		
+		return g;
+	}
+	
+	public static Double sampleSkewness(List<Integer> sample){
+		return sampleSkewness(Doubles.toArray(sample));
+	}
+	
+	private static Double mean(double[] sample){
+		Double mean = 0.0;
+		
+		for (Double d : sample){
+			mean += d;
+		}
+		
+		mean /= ((double) sample.length);
+		
+		return mean;
+	}
+
+	public static Pair<Integer, Integer> findOptimalLength(String libName, ProjectInfo info, boolean onlyUniqueInsertions, JFrame parent) {
+
+		double maxTests = 200;
+		int maxWinStepSize = 100;
+		
+		double lowerWinLen = 400;
+		double higherWinLen = 1200;
+		double winStep = 50;
+		double lowerBoundThreshold = 0.80;
+		double higherBoundThreshold = 0.92;
+		
+		double thresholdStep = (higherBoundThreshold - lowerBoundThreshold) / ((higherWinLen - lowerWinLen) / winStep);
+		
+		
+		BufferedReader br = null;
+		String line = "";
+		Vector<Integer> numberOfInsertions = new Vector<Integer>();
+		Vector<Integer> positions = new Vector<Integer>();
+		
+		try{
+			
+			br = new BufferedReader(new FileReader(info.getPath() + libName + ".inspou"));
+			
+			line = br.readLine();
+			while(line != null){
+				String tempLine = new String(line);
+				int tempPos = Integer.parseInt(tempLine.substring(0, tempLine.indexOf("\t")));
+				tempLine = tempLine.substring(tempLine.indexOf("\t") + 1);
+				int tempNumOfIns = Integer.parseInt(tempLine.substring(tempLine.indexOf("\t") + 1));
+			
+				positions.add(tempPos);
+				numberOfInsertions.add(tempNumOfIns);
+				
+				line = br.readLine();
+			}
+			
+		}catch(IOException e){
+			logger.error(e.getMessage());
+			return null;
+		}finally{
+			try{
+				br.close();
+			}catch(IOException e){
+				logger.error(e.getMessage());
+				return null;
+			}
+		}
+		
+		int testCount = 0;
+		int tempWinLen = 100;
+		int tempWinStep = 10 < (tempWinLen / 4) ? (tempWinLen / 4) : 10;
+		Double R2 = 1.0;
+		
+		Double threshold = lowerBoundThreshold;
+		((MainFrame)parent).makeWinlenLblVisible(true);
+		while(R2 > threshold || R2.equals(Double.NaN)){
+			logger.debug("Winlen == " + tempWinLen);
+			logger.debug("Winstep == " + tempWinStep);
+			
+			((MainFrame)parent).changeWinLenTo("Testing Window length = " + tempWinLen);
+			
+			Pair<double[], double[]> data = processData(positions, numberOfInsertions, tempWinLen, tempWinStep, onlyUniqueInsertions);
+			data = modifyData(data.getFirst(), data.getSecond());
+			R2 = exponentialLeastSquareFitting(data.getFirst(), data.getSecond());
+			
+			if (R2.equals(Double.NaN)){
+				tempWinLen += winStep;
+				tempWinStep = 10 < (tempWinLen / 4) ? (tempWinLen / 4) : 10;
+				tempWinStep = tempWinStep > maxWinStepSize ? maxWinStepSize : tempWinStep;
+				
+				threshold = tempWinLen > 400 ? (threshold + thresholdStep) : threshold;
+				threshold = tempWinLen > 1400 ? higherBoundThreshold : threshold;
+				logger.debug("Threshhold #" + testCount + ": " + threshold);
+				
+				continue;
+			}
+			
+			testCount++;
+			
+			if (testCount > maxTests){
+				break;
+			}
+			
+			tempWinLen += winStep;
+			tempWinStep = 10 < (tempWinLen / 4) ? (tempWinLen / 4) : 10;
+			tempWinStep = tempWinStep > maxWinStepSize ? maxWinStepSize : tempWinStep;
+			
+			threshold = tempWinLen > 400 ? (threshold + thresholdStep) : threshold;
+			threshold = tempWinLen > 1400 ? higherBoundThreshold : threshold;
+			logger.debug("Threshhold #" + testCount + ": " + threshold);
+		}
+		
+		tempWinStep = 10 > (tempWinLen / 10) ? (tempWinLen / 10) : 10;
+		
+		return new Pair<Integer, Integer>(tempWinLen, tempWinStep);
+	}
+	
+	private static Pair<double[], double[]> modifyData(double[] positions, double[] numberOfInsertions){
+		double sum = (new Sum()).evaluate(numberOfInsertions);
+		double percentile = 2.0 / 100 * sum;
+		
+		double endSum = 0.0;
+		int index = 1;
+		while (endSum < percentile){
+			endSum += numberOfInsertions[numberOfInsertions.length - index];
+			index++;
+		}
+		
+		Vector<Double> newPositions = new Vector<Double>();
+		Vector<Double> newNumOfInsertions = new Vector<Double>();
+		
+		for (int i = 0; i < numberOfInsertions.length - index; i++){
+			newPositions.add(positions[i]);
+			newNumOfInsertions.add(numberOfInsertions[i]);
+		}
+		
+		return new Pair<double[], double[]>(Doubles.toArray(newPositions), Doubles.toArray(newNumOfInsertions));
+	}
+	
+	private static Pair<double[], double[]> processData(List<Integer> positions, List<Integer> numberOfInsertions, int windowLen, int windowStep, boolean onlyUniqueInsertions){
+		Vector<Integer> insertions = new Vector<Integer>();
+		int maxInsertions = 0;
+		int currentPosition = 0;
+		
+		while(currentPosition < positions.get(positions.size() - 1)){
+			int tempCount = 0;
+			
+			for (int i = 0; i < numberOfInsertions.size(); i++){
+				int tempPos = positions.get(i);
+				if(tempPos >= currentPosition && tempPos < currentPosition + windowLen){
+					if (onlyUniqueInsertions)
+						tempCount++;
+					else
+						tempCount += numberOfInsertions.get(i);
+				}
+				
+				if(tempPos > currentPosition + windowLen){
+					break;
+				}
+			}
+			
+			insertions.add(tempCount);
+			if(tempCount > maxInsertions){
+				maxInsertions = tempCount;
+			}
+			
+			currentPosition += windowStep; 
+		}
+		
+		Vector<Integer> xAxis = new Vector<Integer>();
+		Vector<Integer> yAxis = new Vector<Integer>();
+		
+		for (int i = 0; i < maxInsertions + 1; i++){
+			yAxis.addElement(0);
+		}
+		
+		for(int i = 0; i < insertions.size(); i++){
+			yAxis.setElementAt(yAxis.get(insertions.get(i)) + 1, insertions.get(i));
+		}
+		
+		for(int i = 0; i < yAxis.size(); i++){
+			xAxis.add(i);
+		}
+		
+		return new Pair<double[], double[]>(Doubles.toArray(xAxis), Doubles.toArray(yAxis));
+	}
+	
+}
diff --git a/src/log4j.properties b/src/log4j.properties
new file mode 100644
index 0000000..466b7ab
--- /dev/null
+++ b/src/log4j.properties
@@ -0,0 +1,31 @@
+# Define the types of logger and level of logging    
+log4j.rootLogger = DEBUG,console,FILE
+
+# Define the File appender    
+log4j.appender.FILE=org.apache.log4j.FileAppender    
+
+# Define Console Appender    
+log4j.appender.console=org.apache.log4j.ConsoleAppender    
+
+# Define the layout for console appender. If you do not 
+# define it, you will get an error    
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+
+# Set the name of the file    
+log4j.appender.FILE.File=log.out
+
+# Set the immediate flush to true (default)    
+log4j.appender.FILE.ImmediateFlush=true
+
+# Set the console threshold (It is better to be OFF)    
+log4j.appender.console.Threshold=OFF
+
+# Set the file threshold (It is better to be error)
+log4j.appender.FILE.Threshold=ERROR
+
+# Set the append to false, overwrite    
+log4j.appender.FILE.Append=false
+
+# Define the layout for file appender    
+log4j.appender.FILE.layout=org.apache.log4j.PatternLayout    
+log4j.appender.FILE.layout.conversionPattern=%m%n
\ No newline at end of file
diff --git a/src/resources/bowtie-bin/linux/bowtie2 b/src/resources/bowtie-bin/linux/bowtie2
new file mode 100755
index 0000000..497a851
--- /dev/null
+++ b/src/resources/bowtie-bin/linux/bowtie2
@@ -0,0 +1,583 @@
+#!/usr/bin/env perl
+
+#
+# Copyright 2011, Ben Langmead <langmea at cs.jhu.edu>
+#
+# This file is part of Bowtie 2.
+#
+# Bowtie 2 is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Bowtie 2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Bowtie 2.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# bowtie2:
+#
+# A wrapper script for bowtie2.  Provides various advantages over running
+# bowtie2 directly, including:
+#
+# 1. Handling compressed inputs
+# 2. Redirecting output to various files
+# 3. Output directly to bam (not currently supported)
+
+use strict;
+use warnings;
+use Getopt::Long qw(GetOptions);
+use File::Spec;
+use POSIX;
+
+
+my ($vol,$script_path,$prog);
+$prog = File::Spec->rel2abs( __FILE__ );
+
+while (-f $prog && -l $prog){
+    my (undef, $dir, undef) = File::Spec->splitpath($prog);
+    $prog = File::Spec->rel2abs(readlink($prog), $dir);
+}
+
+($vol,$script_path,$prog) 
+                = File::Spec->splitpath($prog);
+my $os_is_nix   = ($^O eq "linux") || ($^O eq "darwin");
+my $align_bin_s = $os_is_nix ? 'bowtie2-align-s' : 'bowtie2-align-s.exe'; 
+my $build_bin   = $os_is_nix ? 'bowtie2-build' : 'bowtie2-build.exe';               
+my $align_bin_l = $os_is_nix ? 'bowtie2-align-l' : 'bowtie2-align-l.exe'; 
+my $align_prog_s= File::Spec->catpath($vol,$script_path,$align_bin_s);
+my $align_prog_l= File::Spec->catpath($vol,$script_path,$align_bin_l);
+my $align_prog  = $align_prog_s;
+my $idx_ext_l     = 'bt2l'; 
+my $idx_ext_s     = 'bt2'; 
+my $idx_ext       = $idx_ext_s; 
+my %signo       = ();
+my @signame     = ();
+
+{
+	# Get signal info
+	use Config;
+	my $i = 0;
+	for my $name (split(' ', $Config{sig_name})) {
+		$signo{$name} = $i;
+		$signame[$i] = $name;
+		$i++;
+	}
+}
+
+(-x "$align_prog") ||
+	Fail("Expected bowtie2 to be in same directory with bowtie2-align:\n$script_path\n");
+
+# Get description of arguments from Bowtie 2 so that we can distinguish Bowtie
+# 2 args from wrapper args
+sub getBt2Desc($) {
+	my $d = shift;
+	my $cmd = "$align_prog --wrapper basic-0 --arg-desc";
+	open(my $fh, "$cmd |") || Fail("Failed to run command '$cmd'\n");
+	while(readline $fh) {
+		chomp;
+		next if /^\s*$/;
+		my @ts = split(/\t/);
+		$d->{$ts[0]} = $ts[1];
+	}
+	close($fh);
+	$? == 0 || Fail("Description of arguments failed!\n");
+}
+
+my %desc = ();
+my %wrapped = ("1" => 1, "2" => 1);
+getBt2Desc(\%desc);
+
+# Given an option like -1, determine whether it's wrapped (i.e. should be
+# handled by this script rather than being passed along to Bowtie 2)
+sub isWrapped($) { return defined($wrapped{$_[0]}); }
+
+my @orig_argv = @ARGV;
+
+my @bt2w_args = (); # options for wrapper
+my @bt2_args  = (); # options for Bowtie 2
+my $saw_dd = 0;
+for(0..$#ARGV) {
+	if($ARGV[$_] eq "--") {
+		$saw_dd = 1;
+		next;
+	}
+	push @bt2w_args, $ARGV[$_] if !$saw_dd;
+	push @bt2_args,  $ARGV[$_] if  $saw_dd;
+}
+if(!$saw_dd) {
+	@bt2_args = @bt2w_args;
+	@bt2w_args= ();
+}
+
+my $debug = 0;
+my %read_fns = ();
+my %read_compress = ();
+my $cap_out = undef;       # Filename for passthrough
+my $no_unal = 0;
+my $large_idx = 0;
+# Remove whitespace
+for my $i (0..$#bt2_args) {
+	$bt2_args[$i]=~ s/^\s+//; $bt2_args[$i] =~ s/\s+$//;
+}
+
+# We've handled arguments that the user has explicitly directed either to the
+# wrapper or to bowtie2, now we capture some of the bowtie2 arguments that
+# ought to be handled in the wrapper
+for(my $i = 0; $i < scalar(@bt2_args); $i++) {
+	next unless defined($bt2_args[$i]);
+	my $arg = $bt2_args[$i];
+	my @args = split(/=/, $arg);
+	if(scalar(@args) > 2) {
+		$args[1] = join("=", @args[1..$#args]);
+	}
+	$arg = $args[0];
+	if($arg eq "-U" || $arg eq "--unpaired") {
+		$bt2_args[$i] = undef;
+		$arg =~ s/^-U//; $arg =~ s/^--unpaired//;
+		if($arg ne "") {
+			# Argument was part of this token
+			my @args = split(/,/, $arg);
+			for my $a (@args) { push @bt2w_args, ("-U", $a); }
+		} else {
+			# Argument is in the next token
+			$i < scalar(@bt2_args)-1 || Fail("Argument expected in next token!\n");
+			$i++;
+			my @args = split(/,/, $bt2_args[$i]);
+			for my $a (@args) { push @bt2w_args, ("-U", $a); }
+			$bt2_args[$i] = undef;
+		}
+	}
+	if($arg =~ /^--?([12])/ && $arg !~ /^--?12/) {
+		my $mate = $1;
+		$bt2_args[$i] = undef;
+		$arg =~ s/^--?[12]//;
+		if($arg ne "") {
+			# Argument was part of this token
+			my @args = split(/,/, $arg);
+			for my $a (@args) { push @bt2w_args, ("-$mate", $a); }
+		} else {
+			# Argument is in the next token
+			$i < scalar(@bt2_args)-1 || Fail("Argument expected in next token!\n");
+			$i++;
+			my @args = split(/,/, $bt2_args[$i]);
+			for my $a (@args) { push @bt2w_args, ("-$mate", $a); }
+			$bt2_args[$i] = undef;
+		}
+	}
+	if($arg eq "--debug") {
+		$debug = 1;
+		$bt2_args[$i] = undef;
+	}
+	if($arg eq "--no-unal") {
+		$no_unal = 1;
+		$bt2_args[$i] = undef;
+	}
+	if($arg eq "--large-index") {
+		$large_idx = 1;
+		$bt2_args[$i] = undef;
+	}
+	for my $rarg ("un-conc", "al-conc", "un", "al") {
+		if($arg =~ /^--${rarg}$/ || $arg =~ /^--${rarg}-gz$/ || $arg =~ /^--${rarg}-bz2$/) {
+			$bt2_args[$i] = undef;
+			if(scalar(@args) > 1 && $args[1] ne "") {
+				$read_fns{$rarg} = $args[1];
+			} else {
+				$i < scalar(@bt2_args)-1 || Fail("--${rarg}* option takes an argument.\n");
+				$read_fns{$rarg} = $bt2_args[$i+1];
+				$bt2_args[$i+1] = undef;
+			}
+			$read_compress{$rarg} = "";
+			$read_compress{$rarg} = "gzip"  if $arg eq "--${rarg}-gz";
+			$read_compress{$rarg} = "bzip2" if $arg eq "--${rarg}-bz2";
+			last;
+		}
+	}
+}
+# If the user asked us to redirect some reads to files, or to suppress
+# unaligned reads, then we need to capture the output from Bowtie 2 and pass it
+# through this wrapper.
+my $passthru = 0;
+if(scalar(keys %read_fns) > 0 || $no_unal) {
+	$passthru = 1;
+	push @bt2_args, "--passthrough";
+	$cap_out = "-";
+	for(my $i = 0; $i < scalar(@bt2_args); $i++) {
+		next unless defined($bt2_args[$i]);
+		my $arg = $bt2_args[$i];
+		if($arg eq "-S" || $arg eq "--output") {
+			$i < scalar(@bt2_args)-1 || Fail("-S/--output takes an argument.\n");
+			$cap_out = $bt2_args[$i+1];
+			$bt2_args[$i] = undef;
+			$bt2_args[$i+1] = undef;
+		}
+	}
+}
+my @tmp = ();
+for (@bt2_args) { push(@tmp, $_) if defined($_); }
+ at bt2_args = @tmp;
+
+my @unps = ();
+my @mate1s = ();
+my @mate2s = ();
+my @to_delete = ();
+my $temp_dir = "/tmp";
+my $bam_out = 0;
+my $ref_str = undef;
+my $no_pipes = 0;
+my $keep = 0;
+my $verbose = 0;
+my $readpipe = undef;
+my $log_fName = undef;
+my $help = 0;
+
+my @bt2w_args_cp = (@bt2w_args>0) ? @bt2w_args : @bt2_args;
+Getopt::Long::Configure("pass_through","no_ignore_case");
+
+my @old_ARGV = @ARGV;
+ at ARGV = @bt2w_args_cp;
+
+GetOptions(
+	"1=s"                           => \@mate1s,
+	"2=s"                           => \@mate2s,
+	"reads|U=s"                     => \@unps,
+	"temp-directory=s"              => \$temp_dir,
+	"bam"                           => \$bam_out,
+	"no-named-pipes"                => \$no_pipes,
+	"ref-string|reference-string=s" => \$ref_str,
+	"keep"                          => \$keep,
+	"verbose"                       => \$verbose,
+	"log-file=s"                    => \$log_fName,
+	"help|h"                        => \$help
+);
+
+ at ARGV = @old_ARGV;
+
+my $old_stderr;
+
+if ($log_fName) {
+    open($old_stderr, ">&STDERR") or Fail("Cannot dup STDERR!\n");
+    open(STDERR, ">", $log_fName) or Fail("Cannot redirect to log file $log_fName.\n");
+}
+
+Info("Before arg handling:\n");
+Info("  Wrapper args:\n[ @bt2w_args ]\n");
+Info("  Binary args:\n[ @bt2_args ]\n");
+
+sub cat_file($$) {
+	my ($ifn, $ofh) = @_;
+	my $ifh = undef;
+	if($ifn =~ /\.gz$/) {
+		open($ifh, "gzip -dc $ifn |") ||
+			 Fail("Could not open gzipped read file: $ifn \n");
+	} elsif($ifn =~ /\.bz2/) {
+		open($ifh, "bzip2 -dc $ifn |") ||
+			Fail("Could not open bzip2ed read file: $ifn \n");
+	} else {
+		open($ifh, $ifn) || Fail("Could not open read file: $ifn \n");
+	}
+	while(readline $ifh) { print {$ofh} $_; }
+	close($ifh);
+}
+
+# Return non-zero if and only if the input should be wrapped (i.e. because
+# it's compressed).
+sub wrapInput($$$) {
+	my ($unps, $mate1s, $mate2s) = @_;
+	for my $fn (@$unps, @$mate1s, @$mate2s) {
+		return 1 if $fn =~ /\.gz$/ || $fn =~ /\.bz2$/;
+	}
+	return 0;
+}
+
+sub Info {
+    if ($verbose) {
+        print STDERR "(INFO): " , at _;
+    }
+}
+
+sub Error {
+    my @msg = @_;
+    $msg[0] = "(ERR): ".$msg[0];
+    printf STDERR @msg;
+}
+
+sub Fail {
+    Error(@_);
+    die("Exiting now ...\n");    
+}
+
+sub Extract_IndexName_From {
+    my $index_opt = $ref_str ? '--index' : '-x';
+    for (my $i=0; $i<@_; $i++) {
+        if ($_[$i] eq $index_opt){
+            return $_[$i+1];
+        }
+    }
+    Info("Cannot find any index option (--reference-string, --ref-string or -x) in the given command line.\n");    
+}
+
+if(wrapInput(\@unps, \@mate1s, \@mate2s)) {
+	if(scalar(@mate2s) > 0) {
+		#
+		# Wrap paired-end inputs
+		#
+		# Put reads into temporary files or fork off processes to feed named pipes
+		scalar(@mate2s) == scalar(@mate1s) ||
+			Fail("Different number of files specified with --reads/-1 as with -2\n");
+		# Make a named pipe for delivering mate #1s
+		my $m1fn = "$temp_dir/$$.inpipe1";
+		push @to_delete, $m1fn;
+		push @bt2_args, "-1 $m1fn";
+		# Create named pipe 1 for writing
+		if(!$no_pipes) {
+			mkfifo($m1fn, 0700) || Fail("mkfifo($m1fn) failed.\n");
+		}
+		my $pid = 0;
+		$pid = fork() unless $no_pipes;
+		if($pid == 0) {
+			# Open named pipe 1 for writing
+			open(my $ofh, ">$m1fn") || Fail("Can't open '$m1fn' for writing\n");
+			for my $ifn (@mate1s) { cat_file($ifn, $ofh); }
+			close($ofh);
+			exit 0 unless $no_pipes;
+		}
+		# Make a named pipe for delivering mate #2s
+		my $m2fn = "$temp_dir/$$.inpipe2";
+		push @to_delete, $m2fn;
+		push @bt2_args, "-2 $m2fn";
+		# Create named pipe 2 for writing
+		if(!$no_pipes) {
+			mkfifo($m2fn, 0700) || Fail("mkfifo($m2fn) failed.\n");
+		}
+		$pid = 0;
+		$pid = fork() unless $no_pipes;
+		if($pid == 0) {
+			# Open named pipe 2 for writing
+			open(my $ofh, ">$m2fn") || Fail("Can't open '$m2fn' for writing.\n");
+			for my $ifn (@mate2s) { cat_file($ifn, $ofh); }
+			close($ofh);
+			exit 0 unless $no_pipes;
+		}
+	}
+	if(scalar(@unps) > 0) {
+		#
+		# Wrap unpaired inputs.
+		#
+		# Make a named pipe for delivering unpaired reads
+		my $ufn = "$temp_dir/$$.unp";
+		push @to_delete, $ufn;
+		push @bt2_args, "-U $ufn";
+		# Create named pipe 2 for writing
+		if(!$no_pipes) {
+			mkfifo($ufn, 0700) || Fail("mkfifo($ufn) failed.\n");
+		}
+		my $pid = 0;
+		$pid = fork() unless $no_pipes;
+		if($pid == 0) {
+			# Open named pipe 2 for writing
+			open(my $ofh, ">$ufn") || Fail("Can't open '$ufn' for writing.\n");
+			for my $ifn (@unps) { cat_file($ifn, $ofh); }
+			close($ofh);
+			exit 0 unless $no_pipes;
+		}
+	}
+} else {
+	if(scalar(@mate2s) > 0) {
+		# Just pass all the mate arguments along to the binary
+		push @bt2_args, ("-1", join(",", @mate1s));
+		push @bt2_args, ("-2", join(",", @mate2s));
+	}
+	if(scalar(@unps) > 0) {
+		push @bt2_args, ("-U", join(",", @unps));
+	}
+}
+
+if(defined($ref_str)) {
+	my $ofn = "$temp_dir/$$.ref_str.fa";
+	open(my $ofh, ">$ofn") ||
+		Fail("could not open temporary fasta file '$ofn' for writing.\n");
+	print {$ofh} ">1\n$ref_str\n";
+	close($ofh);
+	push @to_delete, $ofn;
+	system("$build_bin $ofn $ofn") == 0 ||
+		Fail("bowtie2-build returned non-0 exit level.\n");
+	push @bt2_args, ("--index", "$ofn");
+	push @to_delete, ("$ofn.1.".$idx_ext, "$ofn.2.".$idx_ext, 
+	                  "$ofn.3.".$idx_ext, "$ofn.4.".$idx_ext,
+	                  "$ofn.rev.1.".$idx_ext, "$ofn.rev.2.".$idx_ext);
+}
+
+Info("After arg handling:\n");
+Info("  Binary args:\n[ @bt2_args ]\n");
+
+my $index_name = Extract_IndexName_From(@bt2_args);
+
+if ($large_idx) {
+    Info("Using a large index enforced by user.\n");
+    $align_prog  = $align_prog_l;
+    $idx_ext     = $idx_ext_l;
+    if (not -f $index_name.".1.".$idx_ext_l) {
+        Fail("Cannot find the large index ${index_name}.1.${idx_ext_l}\n");
+    }
+    Info("Using large index (${index_name}.1.${idx_ext_l}).\n");
+}
+else {
+    if ((-f $index_name.".1.".$idx_ext_l) && 
+        (not -f $index_name.".1.".$idx_ext_s)) {
+        Info("Cannot find a small index but a large one seems to be present.\n");
+        Info("Switching to using the large index (${index_name}.1.${idx_ext_l}).\n");
+        $align_prog  = $align_prog_l;
+        $idx_ext     = $idx_ext_l;
+    }
+    else {
+        Info("Using the small index (${index_name}.1.${idx_ext_s}).\n")
+    }
+}
+
+my $debug_str = ($debug ? "-debug" : "");
+
+# Construct command invoking bowtie2-align
+my $cmd = "$align_prog$debug_str --wrapper basic-0 ".join(" ", @bt2_args);
+
+# Possibly add read input on an anonymous pipe
+$cmd = "$readpipe $cmd" if defined($readpipe);
+
+Info("$cmd\n");
+my $ret;
+if(defined($cap_out)) {
+	# Open Bowtie 2 pipe
+	open(BT, "$cmd |") || Fail("Could not open Bowtie 2 pipe: '$cmd |'\n");
+	# Open output pipe
+	my $ofh = *STDOUT;
+	my @fhs_to_close = ();
+	if($cap_out ne "-") {
+		open($ofh, ">$cap_out") ||
+			Fail("Could not open output file '$cap_out' for writing.\n");
+	}
+	my %read_fhs = ();
+	for my $i ("al", "un", "al-conc", "un-conc") {
+		if(defined($read_fns{$i})) {
+            my ($vol, $base_spec_dir, $base_fname) = File::Spec->splitpath($read_fns{$i});
+            if (-d $read_fns{$i}) {
+                $base_spec_dir = $read_fns{$i};
+                $base_fname = undef;
+            }
+			if($i =~ /-conc$/) {
+				# Open 2 output files, one for mate 1, one for mate 2
+				my ($fn1, $fn2);
+                if ($base_fname) {
+                    ($fn1, $fn2) = ($base_fname,$base_fname);
+                }
+                else {
+                    ($fn1, $fn2) = ($i.'-mate',$i.'-mate');
+                }
+				if($fn1 =~ /%/) {
+					$fn1 =~ s/%/1/g; $fn2 =~ s/%/2/g;
+				} elsif($fn1 =~ /\.[^.]*$/) {
+					$fn1 =~ s/\.([^.]*)$/.1.$1/;
+					$fn2 =~ s/\.([^.]*)$/.2.$1/;
+				} else {
+					$fn1 .= ".1";
+					$fn2 .= ".2";
+				}
+                $fn1 = File::Spec->catpath($vol,$base_spec_dir,$fn1);
+                $fn2 = File::Spec->catpath($vol,$base_spec_dir,$fn2);
+				$fn1 ne $fn2 || Fail("$fn1\n$fn2\n");
+				my ($redir1, $redir2) = (">$fn1", ">$fn2");
+				$redir1 = "| gzip -c $redir1"  if $read_compress{$i} eq "gzip";
+				$redir1 = "| bzip2 -c $redir1" if $read_compress{$i} eq "bzip2";
+				$redir2 = "| gzip -c $redir2"  if $read_compress{$i} eq "gzip";
+				$redir2 = "| bzip2 -c $redir2" if $read_compress{$i} eq "bzip2";
+				open($read_fhs{$i}{1}, $redir1) || Fail("Could not open --$i mate-1 output file '$fn1'\n");
+				open($read_fhs{$i}{2}, $redir2) || Fail("Could not open --$i mate-2 output file '$fn2'\n");
+				push @fhs_to_close, $read_fhs{$i}{1};
+				push @fhs_to_close, $read_fhs{$i}{2};
+			} else {
+			    my $redir = ">".File::Spec->catpath($vol,$base_spec_dir,$i."-seqs");
+			    if ($base_fname) {
+				    $redir = ">$read_fns{$i}";
+			    }
+				$redir = "| gzip -c $redir"  if $read_compress{$i} eq "gzip";
+				$redir = "| bzip2 -c $redir" if $read_compress{$i} eq "bzip2";
+				open($read_fhs{$i}, $redir) || Fail("Could not open --$i output file '$read_fns{$i}'\n");
+				push @fhs_to_close, $read_fhs{$i};
+			}
+		}
+	}
+	while(<BT>) {
+		chomp;
+		my $filt = 0;
+		unless(substr($_, 0, 1) eq "@") {
+			# If we are supposed to output certain reads to files...
+			my $tab1_i = index($_, "\t") + 1;
+			my $tab2_i = index($_, "\t", $tab1_i);
+			my $fl = substr($_, $tab1_i, $tab2_i - $tab1_i);
+			my $unal = ($fl & 4) != 0;
+			$filt = 1 if $no_unal && $unal;
+			if($passthru) {
+				if(scalar(keys %read_fhs) == 0) {
+					# Next line is read with some whitespace escaped
+					my $l = <BT>;
+				} else {
+					my $mate1 = (($fl &  64) != 0);
+					my $mate2 = (($fl & 128) != 0);
+					my $unp = !$mate1 && !$mate2;
+					my $pair = !$unp;
+					# Next line is read with some whitespace escaped
+					my $l = <BT>;
+					chomp($l);
+					$l =~ s/%(..)/chr(hex($1))/eg;
+					if((defined($read_fhs{un}) || defined($read_fhs{al})) && $unp) {
+						if($unal) {
+							# Failed to align
+							print {$read_fhs{un}} $l if defined($read_fhs{un});
+						} else {
+							# Aligned
+							print {$read_fhs{al}} $l if defined($read_fhs{al});
+						}
+					}
+					if((defined($read_fhs{"un-conc"}) || defined($read_fhs{"al-conc"})) && $pair) {
+						my $conc  = (($fl &   2) != 0);
+						if     ($conc && $mate1) {
+							print {$read_fhs{"al-conc"}{1}} $l if defined($read_fhs{"al-conc"});
+						} elsif($conc && $mate2) {
+							print {$read_fhs{"al-conc"}{2}} $l if defined($read_fhs{"al-conc"});
+						} elsif(!$conc && $mate1) {
+							print {$read_fhs{"un-conc"}{1}} $l if defined($read_fhs{"un-conc"});
+						} elsif(!$conc && $mate2) {
+							print {$read_fhs{"un-conc"}{2}} $l if defined($read_fhs{"un-conc"});
+						}
+					}
+				}
+			}
+		}
+		print {$ofh} "$_\n" if !$filt;
+	}
+	for my $k (@fhs_to_close) { close($k); }
+	close($ofh);
+	close(BT);
+	$ret = $?;
+} else {
+	$ret = system($cmd);
+}
+if(!$keep) { for(@to_delete) { unlink($_); } }
+
+if ($ret == -1) {
+    Error("Failed to execute bowtie2-align: $!\n");
+	exit 1;
+} elsif ($ret & 127) {
+	my $signm = "(unknown)";
+	$signm = $signame[$ret & 127] if defined($signame[$ret & 127]);
+	my $ad = "";
+	$ad = "(core dumped)" if (($ret & 128) != 0);
+    Error("bowtie2-align died with signal %d (%s) $ad\n", ($ret & 127), $signm);
+	exit 1;
+} elsif($ret != 0) {
+	Error("bowtie2-align exited with value %d\n", ($ret >> 8));
+}
+exit ($ret >> 8);
diff --git a/src/resources/bowtie-bin/linux/bowtie2-align-l b/src/resources/bowtie-bin/linux/bowtie2-align-l
new file mode 100755
index 0000000..8e1d502
Binary files /dev/null and b/src/resources/bowtie-bin/linux/bowtie2-align-l differ
diff --git a/src/resources/bowtie-bin/linux/bowtie2-align-s b/src/resources/bowtie-bin/linux/bowtie2-align-s
new file mode 100755
index 0000000..f25cbb2
Binary files /dev/null and b/src/resources/bowtie-bin/linux/bowtie2-align-s differ
diff --git a/src/resources/bowtie-bin/linux/bowtie2-build b/src/resources/bowtie-bin/linux/bowtie2-build
new file mode 100755
index 0000000..d448e2b
--- /dev/null
+++ b/src/resources/bowtie-bin/linux/bowtie2-build
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+"""
+ Copyright 2014, Ben Langmead <langmea at cs.jhu.edu>
+
+ This file is part of Bowtie 2.
+
+ Bowtie 2 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bowtie 2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Bowtie 2.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+
+import os
+import sys
+import inspect
+import logging
+
+
+def build_args():
+    """
+    Parse the wrapper arguments. Returns the options,<programm arguments> tuple.
+    """
+
+    parsed_args = {}
+    to_remove = []
+    argv = sys.argv[:]
+    for i, arg in enumerate(argv):
+        if arg == '--large-index':
+            parsed_args[arg] = ""
+            to_remove.append(i)
+        elif arg == '--debug':
+            parsed_args[arg] = ""
+            to_remove.append(i)
+        elif arg == '--verbose':
+            parsed_args[arg] = ""
+            to_remove.append(i)
+
+    for i in reversed(to_remove):
+        del argv[i]
+
+    return parsed_args, argv
+
+
+def main():
+    logging.basicConfig(level=logging.ERROR,
+                        format='%(levelname)s: %(message)s'
+                        )
+    delta               = 200
+    small_index_max_size= 4 * 1024**3 - delta
+    build_bin_name      = "bowtie2-build"
+    build_bin_s         = "bowtie2-build-s"
+    build_bin_l         = "bowtie2-build-l"
+    curr_script         = os.path.realpath(inspect.getsourcefile(main))
+    ex_path             = os.path.dirname(curr_script)
+    build_bin_spec      = os.path.join(ex_path,build_bin_s)
+
+    options, argv = build_args()
+
+    if '--verbose' in options:
+        logging.getLogger().setLevel(logging.INFO)
+        
+    if '--debug' in options:
+        build_bin_spec += '-debug'
+        build_bin_l += '-debug'
+
+    if '--large-index' in options:
+        build_bin_spec = os.path.join(ex_path,build_bin_l)
+    elif len(argv) >= 2:
+        ref_fnames = argv[-2]
+        tot_size = 0
+        for fn in ref_fnames.split(','):
+            if os.path.exists(fn):
+                statinfo = os.stat(fn)
+                tot_size += statinfo.st_size
+        if tot_size > small_index_max_size:
+            build_bin_spec = os.path.join(ex_path,build_bin_l)
+
+    argv[0] = build_bin_name
+    argv.insert(1, 'basic-0')
+    argv.insert(1, '--wrapper')
+    logging.info('Command: %s %s' % (build_bin_spec, ' '.join(argv[1:])))
+    os.execv(build_bin_spec, argv)
+
+if __name__ == "__main__":
+    main()
+
+
+
diff --git a/src/resources/bowtie-bin/linux/bowtie2-build-l b/src/resources/bowtie-bin/linux/bowtie2-build-l
new file mode 100755
index 0000000..69aa226
Binary files /dev/null and b/src/resources/bowtie-bin/linux/bowtie2-build-l differ
diff --git a/src/resources/bowtie-bin/linux/bowtie2-build-s b/src/resources/bowtie-bin/linux/bowtie2-build-s
new file mode 100755
index 0000000..dc95cc9
Binary files /dev/null and b/src/resources/bowtie-bin/linux/bowtie2-build-s differ
diff --git a/src/resources/bowtie-bin/mac/bowtie2 b/src/resources/bowtie-bin/mac/bowtie2
new file mode 100644
index 0000000..497a851
--- /dev/null
+++ b/src/resources/bowtie-bin/mac/bowtie2
@@ -0,0 +1,583 @@
+#!/usr/bin/env perl
+
+#
+# Copyright 2011, Ben Langmead <langmea at cs.jhu.edu>
+#
+# This file is part of Bowtie 2.
+#
+# Bowtie 2 is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# Bowtie 2 is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Bowtie 2.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# bowtie2:
+#
+# A wrapper script for bowtie2.  Provides various advantages over running
+# bowtie2 directly, including:
+#
+# 1. Handling compressed inputs
+# 2. Redirecting output to various files
+# 3. Output directly to bam (not currently supported)
+
+use strict;
+use warnings;
+use Getopt::Long qw(GetOptions);
+use File::Spec;
+use POSIX;
+
+
+my ($vol,$script_path,$prog);
+$prog = File::Spec->rel2abs( __FILE__ );
+
+while (-f $prog && -l $prog){
+    my (undef, $dir, undef) = File::Spec->splitpath($prog);
+    $prog = File::Spec->rel2abs(readlink($prog), $dir);
+}
+
+($vol,$script_path,$prog) 
+                = File::Spec->splitpath($prog);
+my $os_is_nix   = ($^O eq "linux") || ($^O eq "darwin");
+my $align_bin_s = $os_is_nix ? 'bowtie2-align-s' : 'bowtie2-align-s.exe'; 
+my $build_bin   = $os_is_nix ? 'bowtie2-build' : 'bowtie2-build.exe';               
+my $align_bin_l = $os_is_nix ? 'bowtie2-align-l' : 'bowtie2-align-l.exe'; 
+my $align_prog_s= File::Spec->catpath($vol,$script_path,$align_bin_s);
+my $align_prog_l= File::Spec->catpath($vol,$script_path,$align_bin_l);
+my $align_prog  = $align_prog_s;
+my $idx_ext_l     = 'bt2l'; 
+my $idx_ext_s     = 'bt2'; 
+my $idx_ext       = $idx_ext_s; 
+my %signo       = ();
+my @signame     = ();
+
+{
+	# Get signal info
+	use Config;
+	my $i = 0;
+	for my $name (split(' ', $Config{sig_name})) {
+		$signo{$name} = $i;
+		$signame[$i] = $name;
+		$i++;
+	}
+}
+
+(-x "$align_prog") ||
+	Fail("Expected bowtie2 to be in same directory with bowtie2-align:\n$script_path\n");
+
+# Get description of arguments from Bowtie 2 so that we can distinguish Bowtie
+# 2 args from wrapper args
+sub getBt2Desc($) {
+	my $d = shift;
+	my $cmd = "$align_prog --wrapper basic-0 --arg-desc";
+	open(my $fh, "$cmd |") || Fail("Failed to run command '$cmd'\n");
+	while(readline $fh) {
+		chomp;
+		next if /^\s*$/;
+		my @ts = split(/\t/);
+		$d->{$ts[0]} = $ts[1];
+	}
+	close($fh);
+	$? == 0 || Fail("Description of arguments failed!\n");
+}
+
+my %desc = ();
+my %wrapped = ("1" => 1, "2" => 1);
+getBt2Desc(\%desc);
+
+# Given an option like -1, determine whether it's wrapped (i.e. should be
+# handled by this script rather than being passed along to Bowtie 2)
+sub isWrapped($) { return defined($wrapped{$_[0]}); }
+
+my @orig_argv = @ARGV;
+
+my @bt2w_args = (); # options for wrapper
+my @bt2_args  = (); # options for Bowtie 2
+my $saw_dd = 0;
+for(0..$#ARGV) {
+	if($ARGV[$_] eq "--") {
+		$saw_dd = 1;
+		next;
+	}
+	push @bt2w_args, $ARGV[$_] if !$saw_dd;
+	push @bt2_args,  $ARGV[$_] if  $saw_dd;
+}
+if(!$saw_dd) {
+	@bt2_args = @bt2w_args;
+	@bt2w_args= ();
+}
+
+my $debug = 0;
+my %read_fns = ();
+my %read_compress = ();
+my $cap_out = undef;       # Filename for passthrough
+my $no_unal = 0;
+my $large_idx = 0;
+# Remove whitespace
+for my $i (0..$#bt2_args) {
+	$bt2_args[$i]=~ s/^\s+//; $bt2_args[$i] =~ s/\s+$//;
+}
+
+# We've handled arguments that the user has explicitly directed either to the
+# wrapper or to bowtie2, now we capture some of the bowtie2 arguments that
+# ought to be handled in the wrapper
+for(my $i = 0; $i < scalar(@bt2_args); $i++) {
+	next unless defined($bt2_args[$i]);
+	my $arg = $bt2_args[$i];
+	my @args = split(/=/, $arg);
+	if(scalar(@args) > 2) {
+		$args[1] = join("=", @args[1..$#args]);
+	}
+	$arg = $args[0];
+	if($arg eq "-U" || $arg eq "--unpaired") {
+		$bt2_args[$i] = undef;
+		$arg =~ s/^-U//; $arg =~ s/^--unpaired//;
+		if($arg ne "") {
+			# Argument was part of this token
+			my @args = split(/,/, $arg);
+			for my $a (@args) { push @bt2w_args, ("-U", $a); }
+		} else {
+			# Argument is in the next token
+			$i < scalar(@bt2_args)-1 || Fail("Argument expected in next token!\n");
+			$i++;
+			my @args = split(/,/, $bt2_args[$i]);
+			for my $a (@args) { push @bt2w_args, ("-U", $a); }
+			$bt2_args[$i] = undef;
+		}
+	}
+	if($arg =~ /^--?([12])/ && $arg !~ /^--?12/) {
+		my $mate = $1;
+		$bt2_args[$i] = undef;
+		$arg =~ s/^--?[12]//;
+		if($arg ne "") {
+			# Argument was part of this token
+			my @args = split(/,/, $arg);
+			for my $a (@args) { push @bt2w_args, ("-$mate", $a); }
+		} else {
+			# Argument is in the next token
+			$i < scalar(@bt2_args)-1 || Fail("Argument expected in next token!\n");
+			$i++;
+			my @args = split(/,/, $bt2_args[$i]);
+			for my $a (@args) { push @bt2w_args, ("-$mate", $a); }
+			$bt2_args[$i] = undef;
+		}
+	}
+	if($arg eq "--debug") {
+		$debug = 1;
+		$bt2_args[$i] = undef;
+	}
+	if($arg eq "--no-unal") {
+		$no_unal = 1;
+		$bt2_args[$i] = undef;
+	}
+	if($arg eq "--large-index") {
+		$large_idx = 1;
+		$bt2_args[$i] = undef;
+	}
+	for my $rarg ("un-conc", "al-conc", "un", "al") {
+		if($arg =~ /^--${rarg}$/ || $arg =~ /^--${rarg}-gz$/ || $arg =~ /^--${rarg}-bz2$/) {
+			$bt2_args[$i] = undef;
+			if(scalar(@args) > 1 && $args[1] ne "") {
+				$read_fns{$rarg} = $args[1];
+			} else {
+				$i < scalar(@bt2_args)-1 || Fail("--${rarg}* option takes an argument.\n");
+				$read_fns{$rarg} = $bt2_args[$i+1];
+				$bt2_args[$i+1] = undef;
+			}
+			$read_compress{$rarg} = "";
+			$read_compress{$rarg} = "gzip"  if $arg eq "--${rarg}-gz";
+			$read_compress{$rarg} = "bzip2" if $arg eq "--${rarg}-bz2";
+			last;
+		}
+	}
+}
+# If the user asked us to redirect some reads to files, or to suppress
+# unaligned reads, then we need to capture the output from Bowtie 2 and pass it
+# through this wrapper.
+my $passthru = 0;
+if(scalar(keys %read_fns) > 0 || $no_unal) {
+	$passthru = 1;
+	push @bt2_args, "--passthrough";
+	$cap_out = "-";
+	for(my $i = 0; $i < scalar(@bt2_args); $i++) {
+		next unless defined($bt2_args[$i]);
+		my $arg = $bt2_args[$i];
+		if($arg eq "-S" || $arg eq "--output") {
+			$i < scalar(@bt2_args)-1 || Fail("-S/--output takes an argument.\n");
+			$cap_out = $bt2_args[$i+1];
+			$bt2_args[$i] = undef;
+			$bt2_args[$i+1] = undef;
+		}
+	}
+}
+my @tmp = ();
+for (@bt2_args) { push(@tmp, $_) if defined($_); }
+ at bt2_args = @tmp;
+
+my @unps = ();
+my @mate1s = ();
+my @mate2s = ();
+my @to_delete = ();
+my $temp_dir = "/tmp";
+my $bam_out = 0;
+my $ref_str = undef;
+my $no_pipes = 0;
+my $keep = 0;
+my $verbose = 0;
+my $readpipe = undef;
+my $log_fName = undef;
+my $help = 0;
+
+my @bt2w_args_cp = (@bt2w_args>0) ? @bt2w_args : @bt2_args;
+Getopt::Long::Configure("pass_through","no_ignore_case");
+
+my @old_ARGV = @ARGV;
+ at ARGV = @bt2w_args_cp;
+
+GetOptions(
+	"1=s"                           => \@mate1s,
+	"2=s"                           => \@mate2s,
+	"reads|U=s"                     => \@unps,
+	"temp-directory=s"              => \$temp_dir,
+	"bam"                           => \$bam_out,
+	"no-named-pipes"                => \$no_pipes,
+	"ref-string|reference-string=s" => \$ref_str,
+	"keep"                          => \$keep,
+	"verbose"                       => \$verbose,
+	"log-file=s"                    => \$log_fName,
+	"help|h"                        => \$help
+);
+
+ at ARGV = @old_ARGV;
+
+my $old_stderr;
+
+if ($log_fName) {
+    open($old_stderr, ">&STDERR") or Fail("Cannot dup STDERR!\n");
+    open(STDERR, ">", $log_fName) or Fail("Cannot redirect to log file $log_fName.\n");
+}
+
+Info("Before arg handling:\n");
+Info("  Wrapper args:\n[ @bt2w_args ]\n");
+Info("  Binary args:\n[ @bt2_args ]\n");
+
+sub cat_file($$) {
+	my ($ifn, $ofh) = @_;
+	my $ifh = undef;
+	if($ifn =~ /\.gz$/) {
+		open($ifh, "gzip -dc $ifn |") ||
+			 Fail("Could not open gzipped read file: $ifn \n");
+	} elsif($ifn =~ /\.bz2/) {
+		open($ifh, "bzip2 -dc $ifn |") ||
+			Fail("Could not open bzip2ed read file: $ifn \n");
+	} else {
+		open($ifh, $ifn) || Fail("Could not open read file: $ifn \n");
+	}
+	while(readline $ifh) { print {$ofh} $_; }
+	close($ifh);
+}
+
+# Return non-zero if and only if the input should be wrapped (i.e. because
+# it's compressed).
+sub wrapInput($$$) {
+	my ($unps, $mate1s, $mate2s) = @_;
+	for my $fn (@$unps, @$mate1s, @$mate2s) {
+		return 1 if $fn =~ /\.gz$/ || $fn =~ /\.bz2$/;
+	}
+	return 0;
+}
+
+sub Info {
+    if ($verbose) {
+        print STDERR "(INFO): " , at _;
+    }
+}
+
+sub Error {
+    my @msg = @_;
+    $msg[0] = "(ERR): ".$msg[0];
+    printf STDERR @msg;
+}
+
+sub Fail {
+    Error(@_);
+    die("Exiting now ...\n");    
+}
+
+sub Extract_IndexName_From {
+    my $index_opt = $ref_str ? '--index' : '-x';
+    for (my $i=0; $i<@_; $i++) {
+        if ($_[$i] eq $index_opt){
+            return $_[$i+1];
+        }
+    }
+    Info("Cannot find any index option (--reference-string, --ref-string or -x) in the given command line.\n");    
+}
+
+if(wrapInput(\@unps, \@mate1s, \@mate2s)) {
+	if(scalar(@mate2s) > 0) {
+		#
+		# Wrap paired-end inputs
+		#
+		# Put reads into temporary files or fork off processes to feed named pipes
+		scalar(@mate2s) == scalar(@mate1s) ||
+			Fail("Different number of files specified with --reads/-1 as with -2\n");
+		# Make a named pipe for delivering mate #1s
+		my $m1fn = "$temp_dir/$$.inpipe1";
+		push @to_delete, $m1fn;
+		push @bt2_args, "-1 $m1fn";
+		# Create named pipe 1 for writing
+		if(!$no_pipes) {
+			mkfifo($m1fn, 0700) || Fail("mkfifo($m1fn) failed.\n");
+		}
+		my $pid = 0;
+		$pid = fork() unless $no_pipes;
+		if($pid == 0) {
+			# Open named pipe 1 for writing
+			open(my $ofh, ">$m1fn") || Fail("Can't open '$m1fn' for writing\n");
+			for my $ifn (@mate1s) { cat_file($ifn, $ofh); }
+			close($ofh);
+			exit 0 unless $no_pipes;
+		}
+		# Make a named pipe for delivering mate #2s
+		my $m2fn = "$temp_dir/$$.inpipe2";
+		push @to_delete, $m2fn;
+		push @bt2_args, "-2 $m2fn";
+		# Create named pipe 2 for writing
+		if(!$no_pipes) {
+			mkfifo($m2fn, 0700) || Fail("mkfifo($m2fn) failed.\n");
+		}
+		$pid = 0;
+		$pid = fork() unless $no_pipes;
+		if($pid == 0) {
+			# Open named pipe 2 for writing
+			open(my $ofh, ">$m2fn") || Fail("Can't open '$m2fn' for writing.\n");
+			for my $ifn (@mate2s) { cat_file($ifn, $ofh); }
+			close($ofh);
+			exit 0 unless $no_pipes;
+		}
+	}
+	if(scalar(@unps) > 0) {
+		#
+		# Wrap unpaired inputs.
+		#
+		# Make a named pipe for delivering unpaired reads
+		my $ufn = "$temp_dir/$$.unp";
+		push @to_delete, $ufn;
+		push @bt2_args, "-U $ufn";
+		# Create named pipe 2 for writing
+		if(!$no_pipes) {
+			mkfifo($ufn, 0700) || Fail("mkfifo($ufn) failed.\n");
+		}
+		my $pid = 0;
+		$pid = fork() unless $no_pipes;
+		if($pid == 0) {
+			# Open named pipe 2 for writing
+			open(my $ofh, ">$ufn") || Fail("Can't open '$ufn' for writing.\n");
+			for my $ifn (@unps) { cat_file($ifn, $ofh); }
+			close($ofh);
+			exit 0 unless $no_pipes;
+		}
+	}
+} else {
+	if(scalar(@mate2s) > 0) {
+		# Just pass all the mate arguments along to the binary
+		push @bt2_args, ("-1", join(",", @mate1s));
+		push @bt2_args, ("-2", join(",", @mate2s));
+	}
+	if(scalar(@unps) > 0) {
+		push @bt2_args, ("-U", join(",", @unps));
+	}
+}
+
+if(defined($ref_str)) {
+	my $ofn = "$temp_dir/$$.ref_str.fa";
+	open(my $ofh, ">$ofn") ||
+		Fail("could not open temporary fasta file '$ofn' for writing.\n");
+	print {$ofh} ">1\n$ref_str\n";
+	close($ofh);
+	push @to_delete, $ofn;
+	system("$build_bin $ofn $ofn") == 0 ||
+		Fail("bowtie2-build returned non-0 exit level.\n");
+	push @bt2_args, ("--index", "$ofn");
+	push @to_delete, ("$ofn.1.".$idx_ext, "$ofn.2.".$idx_ext, 
+	                  "$ofn.3.".$idx_ext, "$ofn.4.".$idx_ext,
+	                  "$ofn.rev.1.".$idx_ext, "$ofn.rev.2.".$idx_ext);
+}
+
+Info("After arg handling:\n");
+Info("  Binary args:\n[ @bt2_args ]\n");
+
+my $index_name = Extract_IndexName_From(@bt2_args);
+
+if ($large_idx) {
+    Info("Using a large index enforced by user.\n");
+    $align_prog  = $align_prog_l;
+    $idx_ext     = $idx_ext_l;
+    if (not -f $index_name.".1.".$idx_ext_l) {
+        Fail("Cannot find the large index ${index_name}.1.${idx_ext_l}\n");
+    }
+    Info("Using large index (${index_name}.1.${idx_ext_l}).\n");
+}
+else {
+    if ((-f $index_name.".1.".$idx_ext_l) && 
+        (not -f $index_name.".1.".$idx_ext_s)) {
+        Info("Cannot find a small index but a large one seems to be present.\n");
+        Info("Switching to using the large index (${index_name}.1.${idx_ext_l}).\n");
+        $align_prog  = $align_prog_l;
+        $idx_ext     = $idx_ext_l;
+    }
+    else {
+        Info("Using the small index (${index_name}.1.${idx_ext_s}).\n")
+    }
+}
+
+my $debug_str = ($debug ? "-debug" : "");
+
+# Construct command invoking bowtie2-align
+my $cmd = "$align_prog$debug_str --wrapper basic-0 ".join(" ", @bt2_args);
+
+# Possibly add read input on an anonymous pipe
+$cmd = "$readpipe $cmd" if defined($readpipe);
+
+Info("$cmd\n");
+my $ret;
+if(defined($cap_out)) {
+	# Open Bowtie 2 pipe
+	open(BT, "$cmd |") || Fail("Could not open Bowtie 2 pipe: '$cmd |'\n");
+	# Open output pipe
+	my $ofh = *STDOUT;
+	my @fhs_to_close = ();
+	if($cap_out ne "-") {
+		open($ofh, ">$cap_out") ||
+			Fail("Could not open output file '$cap_out' for writing.\n");
+	}
+	my %read_fhs = ();
+	for my $i ("al", "un", "al-conc", "un-conc") {
+		if(defined($read_fns{$i})) {
+            my ($vol, $base_spec_dir, $base_fname) = File::Spec->splitpath($read_fns{$i});
+            if (-d $read_fns{$i}) {
+                $base_spec_dir = $read_fns{$i};
+                $base_fname = undef;
+            }
+			if($i =~ /-conc$/) {
+				# Open 2 output files, one for mate 1, one for mate 2
+				my ($fn1, $fn2);
+                if ($base_fname) {
+                    ($fn1, $fn2) = ($base_fname,$base_fname);
+                }
+                else {
+                    ($fn1, $fn2) = ($i.'-mate',$i.'-mate');
+                }
+				if($fn1 =~ /%/) {
+					$fn1 =~ s/%/1/g; $fn2 =~ s/%/2/g;
+				} elsif($fn1 =~ /\.[^.]*$/) {
+					$fn1 =~ s/\.([^.]*)$/.1.$1/;
+					$fn2 =~ s/\.([^.]*)$/.2.$1/;
+				} else {
+					$fn1 .= ".1";
+					$fn2 .= ".2";
+				}
+                $fn1 = File::Spec->catpath($vol,$base_spec_dir,$fn1);
+                $fn2 = File::Spec->catpath($vol,$base_spec_dir,$fn2);
+				$fn1 ne $fn2 || Fail("$fn1\n$fn2\n");
+				my ($redir1, $redir2) = (">$fn1", ">$fn2");
+				$redir1 = "| gzip -c $redir1"  if $read_compress{$i} eq "gzip";
+				$redir1 = "| bzip2 -c $redir1" if $read_compress{$i} eq "bzip2";
+				$redir2 = "| gzip -c $redir2"  if $read_compress{$i} eq "gzip";
+				$redir2 = "| bzip2 -c $redir2" if $read_compress{$i} eq "bzip2";
+				open($read_fhs{$i}{1}, $redir1) || Fail("Could not open --$i mate-1 output file '$fn1'\n");
+				open($read_fhs{$i}{2}, $redir2) || Fail("Could not open --$i mate-2 output file '$fn2'\n");
+				push @fhs_to_close, $read_fhs{$i}{1};
+				push @fhs_to_close, $read_fhs{$i}{2};
+			} else {
+			    my $redir = ">".File::Spec->catpath($vol,$base_spec_dir,$i."-seqs");
+			    if ($base_fname) {
+				    $redir = ">$read_fns{$i}";
+			    }
+				$redir = "| gzip -c $redir"  if $read_compress{$i} eq "gzip";
+				$redir = "| bzip2 -c $redir" if $read_compress{$i} eq "bzip2";
+				open($read_fhs{$i}, $redir) || Fail("Could not open --$i output file '$read_fns{$i}'\n");
+				push @fhs_to_close, $read_fhs{$i};
+			}
+		}
+	}
+	while(<BT>) {
+		chomp;
+		my $filt = 0;
+		unless(substr($_, 0, 1) eq "@") {
+			# If we are supposed to output certain reads to files...
+			my $tab1_i = index($_, "\t") + 1;
+			my $tab2_i = index($_, "\t", $tab1_i);
+			my $fl = substr($_, $tab1_i, $tab2_i - $tab1_i);
+			my $unal = ($fl & 4) != 0;
+			$filt = 1 if $no_unal && $unal;
+			if($passthru) {
+				if(scalar(keys %read_fhs) == 0) {
+					# Next line is read with some whitespace escaped
+					my $l = <BT>;
+				} else {
+					my $mate1 = (($fl &  64) != 0);
+					my $mate2 = (($fl & 128) != 0);
+					my $unp = !$mate1 && !$mate2;
+					my $pair = !$unp;
+					# Next line is read with some whitespace escaped
+					my $l = <BT>;
+					chomp($l);
+					$l =~ s/%(..)/chr(hex($1))/eg;
+					if((defined($read_fhs{un}) || defined($read_fhs{al})) && $unp) {
+						if($unal) {
+							# Failed to align
+							print {$read_fhs{un}} $l if defined($read_fhs{un});
+						} else {
+							# Aligned
+							print {$read_fhs{al}} $l if defined($read_fhs{al});
+						}
+					}
+					if((defined($read_fhs{"un-conc"}) || defined($read_fhs{"al-conc"})) && $pair) {
+						my $conc  = (($fl &   2) != 0);
+						if     ($conc && $mate1) {
+							print {$read_fhs{"al-conc"}{1}} $l if defined($read_fhs{"al-conc"});
+						} elsif($conc && $mate2) {
+							print {$read_fhs{"al-conc"}{2}} $l if defined($read_fhs{"al-conc"});
+						} elsif(!$conc && $mate1) {
+							print {$read_fhs{"un-conc"}{1}} $l if defined($read_fhs{"un-conc"});
+						} elsif(!$conc && $mate2) {
+							print {$read_fhs{"un-conc"}{2}} $l if defined($read_fhs{"un-conc"});
+						}
+					}
+				}
+			}
+		}
+		print {$ofh} "$_\n" if !$filt;
+	}
+	for my $k (@fhs_to_close) { close($k); }
+	close($ofh);
+	close(BT);
+	$ret = $?;
+} else {
+	$ret = system($cmd);
+}
+if(!$keep) { for(@to_delete) { unlink($_); } }
+
+if ($ret == -1) {
+    Error("Failed to execute bowtie2-align: $!\n");
+	exit 1;
+} elsif ($ret & 127) {
+	my $signm = "(unknown)";
+	$signm = $signame[$ret & 127] if defined($signame[$ret & 127]);
+	my $ad = "";
+	$ad = "(core dumped)" if (($ret & 128) != 0);
+    Error("bowtie2-align died with signal %d (%s) $ad\n", ($ret & 127), $signm);
+	exit 1;
+} elsif($ret != 0) {
+	Error("bowtie2-align exited with value %d\n", ($ret >> 8));
+}
+exit ($ret >> 8);
diff --git a/src/resources/bowtie-bin/mac/bowtie2-align-l b/src/resources/bowtie-bin/mac/bowtie2-align-l
new file mode 100644
index 0000000..56fd8ce
Binary files /dev/null and b/src/resources/bowtie-bin/mac/bowtie2-align-l differ
diff --git a/src/resources/bowtie-bin/mac/bowtie2-align-s b/src/resources/bowtie-bin/mac/bowtie2-align-s
new file mode 100644
index 0000000..d18a580
Binary files /dev/null and b/src/resources/bowtie-bin/mac/bowtie2-align-s differ
diff --git a/src/resources/bowtie-bin/mac/bowtie2-build b/src/resources/bowtie-bin/mac/bowtie2-build
new file mode 100644
index 0000000..d448e2b
--- /dev/null
+++ b/src/resources/bowtie-bin/mac/bowtie2-build
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+"""
+ Copyright 2014, Ben Langmead <langmea at cs.jhu.edu>
+
+ This file is part of Bowtie 2.
+
+ Bowtie 2 is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Bowtie 2 is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Bowtie 2.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+
+import os
+import sys
+import inspect
+import logging
+
+
+def build_args():
+    """
+    Parse the wrapper arguments. Returns the options,<programm arguments> tuple.
+    """
+
+    parsed_args = {}
+    to_remove = []
+    argv = sys.argv[:]
+    for i, arg in enumerate(argv):
+        if arg == '--large-index':
+            parsed_args[arg] = ""
+            to_remove.append(i)
+        elif arg == '--debug':
+            parsed_args[arg] = ""
+            to_remove.append(i)
+        elif arg == '--verbose':
+            parsed_args[arg] = ""
+            to_remove.append(i)
+
+    for i in reversed(to_remove):
+        del argv[i]
+
+    return parsed_args, argv
+
+
+def main():
+    logging.basicConfig(level=logging.ERROR,
+                        format='%(levelname)s: %(message)s'
+                        )
+    delta               = 200
+    small_index_max_size= 4 * 1024**3 - delta
+    build_bin_name      = "bowtie2-build"
+    build_bin_s         = "bowtie2-build-s"
+    build_bin_l         = "bowtie2-build-l"
+    curr_script         = os.path.realpath(inspect.getsourcefile(main))
+    ex_path             = os.path.dirname(curr_script)
+    build_bin_spec      = os.path.join(ex_path,build_bin_s)
+
+    options, argv = build_args()
+
+    if '--verbose' in options:
+        logging.getLogger().setLevel(logging.INFO)
+        
+    if '--debug' in options:
+        build_bin_spec += '-debug'
+        build_bin_l += '-debug'
+
+    if '--large-index' in options:
+        build_bin_spec = os.path.join(ex_path,build_bin_l)
+    elif len(argv) >= 2:
+        ref_fnames = argv[-2]
+        tot_size = 0
+        for fn in ref_fnames.split(','):
+            if os.path.exists(fn):
+                statinfo = os.stat(fn)
+                tot_size += statinfo.st_size
+        if tot_size > small_index_max_size:
+            build_bin_spec = os.path.join(ex_path,build_bin_l)
+
+    argv[0] = build_bin_name
+    argv.insert(1, 'basic-0')
+    argv.insert(1, '--wrapper')
+    logging.info('Command: %s %s' % (build_bin_spec, ' '.join(argv[1:])))
+    os.execv(build_bin_spec, argv)
+
+if __name__ == "__main__":
+    main()
+
+
+
diff --git a/src/resources/bowtie-bin/mac/bowtie2-build-l b/src/resources/bowtie-bin/mac/bowtie2-build-l
new file mode 100644
index 0000000..e56b0b2
Binary files /dev/null and b/src/resources/bowtie-bin/mac/bowtie2-build-l differ
diff --git a/src/resources/bowtie-bin/mac/bowtie2-build-s b/src/resources/bowtie-bin/mac/bowtie2-build-s
new file mode 100644
index 0000000..4069452
Binary files /dev/null and b/src/resources/bowtie-bin/mac/bowtie2-build-s differ
diff --git a/src/resources/bowtie-bin/win-64/bowtie2-align-s.exe b/src/resources/bowtie-bin/win-64/bowtie2-align-s.exe
new file mode 100644
index 0000000..f68f377
Binary files /dev/null and b/src/resources/bowtie-bin/win-64/bowtie2-align-s.exe differ
diff --git a/src/resources/bowtie-bin/win-64/bowtie2-build-s.exe b/src/resources/bowtie-bin/win-64/bowtie2-build-s.exe
new file mode 100644
index 0000000..8d41f75
Binary files /dev/null and b/src/resources/bowtie-bin/win-64/bowtie2-build-s.exe differ
diff --git a/src/resources/bwa-0.7.5a.tar.bz2 b/src/resources/bwa-0.7.5a.tar.bz2
new file mode 100644
index 0000000..d3565fb
Binary files /dev/null and b/src/resources/bwa-0.7.5a.tar.bz2 differ
diff --git a/src/resources/done.gif b/src/resources/done.gif
new file mode 100644
index 0000000..0319e6f
Binary files /dev/null and b/src/resources/done.gif differ
diff --git a/src/resources/info.png b/src/resources/info.png
new file mode 100644
index 0000000..b98377a
Binary files /dev/null and b/src/resources/info.png differ
diff --git a/src/resources/install-bwa-redhat.sh b/src/resources/install-bwa-redhat.sh
new file mode 100644
index 0000000..260a147
--- /dev/null
+++ b/src/resources/install-bwa-redhat.sh
@@ -0,0 +1,36 @@
+#SCRIPT=$(readlink -f "$0")
+#SCRIPT_PATH=$(dirname "$SCRIPT")
+#echo $SCRIPT_PATH
+
+if [ "$UID" -ne 0 ]; then
+    echo "You must be root to run this script"
+    exit 1
+fi
+
+# If we're here, we're supposed to have access. Copy the files over
+
+if [ ! -d "/usr/lib/bwa" ]; then
+	# Control will enter here if $DIRECTORY doesn't exist.
+	mkdir /usr/lib/bwa
+fi
+
+if [ -d "/usr/lib/bwa/bwa-0.7.5a.tar.bz2" ]; then
+	rm /usr/lib/bwa/bwa-0.7.5a.tar.bz2
+fi
+
+cp bwa-0.7.5a.tar.bz2 /usr/lib/bwa/
+cd /usr/lib/bwa
+tar -jxf bwa-0.7.5a.tar.bz2
+
+cd bwa-0.7.5a
+make clean
+make
+
+/usr/sbin/alternatives --install /usr/bin/bwa bwa /usr/lib/bwa/bwa-0.7.5a/bwa 20000
+
+
+echo 'BWA program got installed'
+
+exit 0
+
+#/usr/sbin/alternatives --install /usr/bin/bwa 
diff --git a/src/resources/install-bwa-ubuntu.sh b/src/resources/install-bwa-ubuntu.sh
new file mode 100644
index 0000000..0f5fbce
--- /dev/null
+++ b/src/resources/install-bwa-ubuntu.sh
@@ -0,0 +1,38 @@
+#SCRIPT=$(readlink -f "$0")
+#SCRIPT_PATH=$(dirname "$SCRIPT")
+#echo $SCRIPT_PATH
+
+if [ "$UID" -ne 0 ]; then
+    echo "You must be root to run this script"
+    exit 1
+fi
+
+# If we're here, we're supposed to have access. Copy the files over
+
+apt-get install zlib1g-dev
+
+if [ ! -d "/usr/lib/bwa" ]; then
+	# Control will enter here if $DIRECTORY doesn't exist.
+	mkdir /usr/lib/bwa
+fi
+
+if [ -d "/usr/lib/bwa/bwa-0.7.5a.tar.bz2" ]; then
+	rm /usr/lib/bwa/bwa-0.7.5a.tar.bz2
+fi
+
+cp bwa-0.7.5a.tar.bz2 /usr/lib/bwa/
+cd /usr/lib/bwa
+tar -jxf bwa-0.7.5a.tar.bz2
+
+cd bwa-0.7.5a
+make clean
+make
+
+update-alternatives --install /usr/bin/bwa bwa /usr/lib/bwa/bwa-0.7.5a/bwa 1
+
+
+echo 'BWA program got installed'
+
+exit 0
+
+#/usr/sbin/alternatives --install /usr/bin/bwa 
diff --git a/src/resources/legaldisclaimer.png b/src/resources/legaldisclaimer.png
new file mode 100644
index 0000000..e30d519
Binary files /dev/null and b/src/resources/legaldisclaimer.png differ
diff --git a/src/resources/load.gif b/src/resources/load.gif
new file mode 100644
index 0000000..5b33f7e
Binary files /dev/null and b/src/resources/load.gif differ

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/tn-seqexplorer.git



More information about the debian-med-commit mailing list