diff --git a/uk/ac/sanger/artemis/components/alignment/BamView.java b/uk/ac/sanger/artemis/components/alignment/BamView.java
index 9b2c0184bad0ef5e90d47c2d9ad687e0851d3f49..1f09dc1e9b742ed31f67b59c2fbca2da935a5757 100644
--- a/uk/ac/sanger/artemis/components/alignment/BamView.java
+++ b/uk/ac/sanger/artemis/components/alignment/BamView.java
@@ -27,6 +27,7 @@ import java.awt.AlphaComposite;
 import java.awt.BasicStroke;
 import java.awt.BorderLayout;
 import java.awt.Color;
+import java.awt.Component;
 import java.awt.Composite;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
@@ -124,6 +125,8 @@ public class BamView extends JPanel
   private Vector<String> seqNames = new Vector<String>();
   private String bam;
 
+  private SAMRecordFlagPredicate samRecordFlagPredicate;
+  
   private Bases bases;
   private JScrollPane jspView;
   private JScrollBar scrollBar;
@@ -439,7 +442,12 @@ public class BamView extends JPanel
       {
         cnt++;
         SAMRecord samRecord = it.next();
-        readsInView.add(samRecord);
+        
+        if( samRecordFlagPredicate == null ||
+           !samRecordFlagPredicate.testPredicate(samRecord))
+        {
+          readsInView.add(samRecord);
+        }
         
         if(cnt > checkMemAfter)
         {
@@ -1611,6 +1619,42 @@ public class BamView extends JPanel
     { 
       topPanel = new JMenuBar();
       frame.setJMenuBar((JMenuBar)topPanel);
+      
+      JMenu fileMenu = new JMenu("File");
+      topPanel.add(fileMenu);
+
+      JMenuItem readBam = new JMenuItem("Read BAM...");
+      fileMenu.add(readBam);
+      readBam.addActionListener(new ActionListener()
+      {
+        public void actionPerformed(ActionEvent e)
+        {
+          String[] s = new String[0];
+          BamView.main(s);
+          BamView.this.setVisible(false);
+          
+          Component comp = BamView.this;
+          
+          while( !(comp instanceof JFrame) )
+            comp = comp.getParent();
+          ((JFrame)comp).dispose();
+        } 
+      });
+      
+      JMenuItem exit = new JMenuItem("Exit");
+      fileMenu.add(exit);
+      exit.addActionListener(new ActionListener()
+      {
+        public void actionPerformed(ActionEvent e)
+        {
+          int status = JOptionPane.showConfirmDialog(BamView.this, 
+              "Close BamView?", "Close", 
+              JOptionPane.OK_CANCEL_OPTION);
+          if(status != JOptionPane.OK_OPTION)
+            return;
+          System.exit(0);
+        } 
+      });
     }
     
     if(seqNames.size() > 1)
@@ -2004,6 +2048,17 @@ public class BamView extends JPanel
         }
       });
     }
+    
+    JMenuItem filter = new JMenuItem("Filter by Flag...");
+    menu.add(filter);
+    filter.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        new SAMRecordFilter(BamView.this);
+      } 
+    });
+    
   }
   
   public void setVisible(boolean visible)
@@ -2510,6 +2565,19 @@ public class BamView extends JPanel
     viewDetail.appendString("\nSecond Of Pair    "+
         (thisSAMRecord.getSecondOfPairFlag() ? "yes" : "no"), Level.DEBUG);
   }
+
+  protected SAMRecordFlagPredicate getSamRecordFlagPredicate()
+  {
+    return samRecordFlagPredicate;
+  }
+
+  protected void setSamRecordFlagPredicate(
+      SAMRecordFlagPredicate samRecordFlagPredicate)
+  {
+    laststart = -1;
+    lastend = -1;
+    this.samRecordFlagPredicate = samRecordFlagPredicate;
+  }
   
   class PairedRead
   {
@@ -2579,6 +2647,4 @@ public class BamView extends JPanel
         view.jspView.getVerticalScrollBar().getMaximum());
     frame.setVisible(true);
   }
-
-
 }
diff --git a/uk/ac/sanger/artemis/components/alignment/SAMRecordFilter.java b/uk/ac/sanger/artemis/components/alignment/SAMRecordFilter.java
new file mode 100644
index 0000000000000000000000000000000000000000..ecca4ee92bbc16fe98765c5fd879dea3936592c3
--- /dev/null
+++ b/uk/ac/sanger/artemis/components/alignment/SAMRecordFilter.java
@@ -0,0 +1,76 @@
+package uk.ac.sanger.artemis.components.alignment;
+
+import java.awt.GridLayout;
+
+import javax.swing.JCheckBox;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+
+class SAMRecordFilter extends JPanel
+{
+  private static final long serialVersionUID = 1L;
+
+  public SAMRecordFilter(final BamView bamView)
+  {
+    super();
+    int nflags = SAMRecordFlagPredicate.FLAGS.length;
+    setLayout(new GridLayout(nflags, 2));
+
+    final JCheckBox flagCheck[] = new JCheckBox[nflags];
+    for(int j=0; j<nflags; j++)
+    {
+      flagCheck[j] = new JCheckBox(
+          SAMRecordFlagPredicate.FLAGS_DESCRUIPTION[j], false);
+      flagCheck[j].addChangeListener(new ChangeListener()
+      {
+        public void stateChanged(ChangeEvent e)
+        {
+          filterChange(bamView, flagCheck);
+        }            
+      });
+      add(flagCheck[j]);
+    }
+    
+    int status = JOptionPane.showConfirmDialog(bamView, 
+        this, "Filter Out Reads Based on Flag", 
+        JOptionPane.OK_CANCEL_OPTION);
+
+    if(status != JOptionPane.OK_OPTION)
+      return;
+  } 
+  
+  private void filterChange(final BamView bamView,
+                            final JCheckBox flagCheck[])
+  {
+    int nflags = SAMRecordFlagPredicate.FLAGS.length;
+    int flagsChecked = 0;
+    for(int j=0; j<nflags; j++)
+    {
+      if(flagCheck[j].isSelected())
+        flagsChecked++;
+    }
+    
+    bamView.setSamRecordFlagPredicate(null);
+    
+    if(flagsChecked == 0)
+    {
+      bamView.repaint();
+      return;
+    }
+    
+    int flagsOn[] = new int[flagsChecked];
+    int num = 0;
+    for(int j=0; j<nflags; j++)
+    {
+      if(flagCheck[j].isSelected())
+        flagsOn[num++] = SAMRecordFlagPredicate.FLAGS[j];
+    }
+    
+    bamView.setSamRecordFlagPredicate(new SAMRecordFlagPredicate(flagsOn));
+    bamView.repaint();
+  }
+  
+}
\ No newline at end of file
diff --git a/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagPredicate.java b/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagPredicate.java
new file mode 100644
index 0000000000000000000000000000000000000000..dfd71f73e895f7ec02c7372fed887b19a35b94b3
--- /dev/null
+++ b/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagPredicate.java
@@ -0,0 +1,98 @@
+/* SAMRecordPredicate
+ *
+ * This file is part of Artemis
+ * 
+ * Copyright (C) 2009  Genome Research Limited
+ * 
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ **/
+
+package uk.ac.sanger.artemis.components.alignment;
+
+import net.sf.samtools.SAMRecord;
+
+/**
+ *  Test the SAMRecord flag.
+ **/
+public class SAMRecordFlagPredicate implements SAMRecordPredicate
+{
+  private int flag[];
+  
+  private static final int READ_PAIRED_FLAG = 0x1;
+  private static final int PROPER_PAIR_FLAG = 0x2;
+  private static final int READ_UNMAPPED_FLAG = 0x4;
+  private static final int MATE_UNMAPPED_FLAG = 0x8;
+  private static final int READ_STRAND_FLAG = 0x10;
+  private static final int MATE_STRAND_FLAG = 0x20;
+  private static final int FIRST_OF_PAIR_FLAG = 0x40;
+  private static final int SECOND_OF_PAIR_FLAG = 0x80;
+  private static final int NOT_PRIMARY_ALIGNMENT_FLAG = 0x100;
+  private static final int READ_FAILS_VENDOR_QUALITY_CHECK_FLAG = 0x200;
+  private static final int DUPLICATE_READ_FLAG = 0x400;
+  
+  protected static final String[] FLAGS_DESCRUIPTION =
+  {
+    "Read Paired",
+    "Proper Pair",
+    "Read Unmapped",
+    "Mate Unmapped",
+    "Read on Negative Strand",
+    "Mate on Negative Strand",
+    "First of Pair",
+    "Second of Pair",
+    "Not Primary Alignment",
+    "Read Fails Vendor Quality Check",
+    "Duplicate Read"
+  };
+  
+  protected static int[] FLAGS =
+  {
+    READ_PAIRED_FLAG,
+    PROPER_PAIR_FLAG,
+    READ_UNMAPPED_FLAG,
+    MATE_UNMAPPED_FLAG,
+    READ_STRAND_FLAG,
+    MATE_STRAND_FLAG,
+    FIRST_OF_PAIR_FLAG,
+    SECOND_OF_PAIR_FLAG,
+    NOT_PRIMARY_ALIGNMENT_FLAG,
+    READ_FAILS_VENDOR_QUALITY_CHECK_FLAG,
+    DUPLICATE_READ_FLAG
+  };
+
+  
+  public SAMRecordFlagPredicate(int flag[])
+  {
+    this.flag = flag;
+  }
+  
+  /**
+   *  Test the given SAMRecord against this predicate.
+   *  @param feature The SAMRecord to test the predicate against.
+   *  @return Return true if and only if this predicate is true for the given
+   *    SAMRecord.
+   **/
+  public boolean testPredicate (final SAMRecord samRecord)
+  {
+    for(int i=0; i<flag.length; i++)
+    {
+      if((samRecord.getFlags() & flag[i]) == flag[i])
+        return true;
+    }
+    return false;
+  }
+}
+
+
diff --git a/uk/ac/sanger/artemis/components/alignment/SAMRecordPredicate.java b/uk/ac/sanger/artemis/components/alignment/SAMRecordPredicate.java
new file mode 100644
index 0000000000000000000000000000000000000000..4b9fe5ed10c99013a74c2d848393904260c80e40
--- /dev/null
+++ b/uk/ac/sanger/artemis/components/alignment/SAMRecordPredicate.java
@@ -0,0 +1,41 @@
+/* SAMRecordPredicate
+ *
+ * This file is part of Artemis
+ * 
+ * Copyright (C) 2009  Genome Research Limited
+ * 
+ * This program 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 2
+ * of the License, or (at your option) any later version.
+ * 
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ **/
+
+package uk.ac.sanger.artemis.components.alignment;
+
+import net.sf.samtools.SAMRecord;
+
+/**
+ *  Each object that implements this interface represents a predicate that can
+ *  be tested with a SAMRecord reference.
+ **/
+
+public interface SAMRecordPredicate {
+  /**
+   *  Test the given SAMRecord against this predicate.
+   *  @param feature The SAMRecord to test the predicate against.
+   *  @return Return true if and only if this predicate is true for the given
+   *    SAMRecord.
+   **/
+  boolean testPredicate (final SAMRecord samRecord);
+}
+
+