From e52591abba63d6870577773be55b79511d8c138e Mon Sep 17 00:00:00 2001
From: Sean-M <Smoss117@gmail.com>
Date: Wed, 6 Mar 2013 18:20:09 -0500
Subject: [PATCH] to be merged

---
 .../KeywordSearchConfigurationPanel1.java     |    2 +-
 .../KeywordSearchEditListPanel.java           |    8 +-
 .../KeywordSearchIngestModule.java            |   14 +-
 .../KeywordSearchIngestSimplePanel.java       |    8 +-
 .../KeywordSearchListsAbstract.java           | 1050 ++++++++---------
 .../KeywordSearchListsManagementPanel.form    |    2 +-
 .../KeywordSearchListsManagementPanel.java    |    6 +-
 .../KeywordSearchListsViewerPanel.java        |   20 +-
 .../KeywordSearchResultFactory.java           |    2 +-
 Testing/nbproject/project.xml                 |    9 +
 .../autopsy/testing/RegressionTest.java       |    3 +
 11 files changed, 568 insertions(+), 556 deletions(-)

diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchConfigurationPanel1.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchConfigurationPanel1.java
index d22390f0a9..f40185e96b 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchConfigurationPanel1.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchConfigurationPanel1.java
@@ -80,7 +80,7 @@ public void actionPerformed(ActionEvent e) {
             public void actionPerformed(ActionEvent e) {
                 final String FEATURE_NAME = "Save Keyword List";
                 KeywordSearchListsXML writer = KeywordSearchListsXML.getCurrent();
-                KeywordSearchList currentKeywordList = editListPanel.getCurrentKeywordList();
+                KeywordSearchListsAbstract.KeywordSearchList currentKeywordList = editListPanel.getCurrentKeywordList();
 
                 List<Keyword> keywords = currentKeywordList.getKeywords();
                 if (keywords.isEmpty()) {
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java
index c8657a0026..a720dde3ba 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchEditListPanel.java
@@ -57,7 +57,7 @@ class KeywordSearchEditListPanel extends javax.swing.JPanel implements ListSelec
 
     private static Logger logger = Logger.getLogger(KeywordSearchEditListPanel.class.getName());
     private KeywordTableModel tableModel;
-    private KeywordSearchList currentKeywordList;
+    private KeywordSearchListsAbstract.KeywordSearchList currentKeywordList;
 
     
     private boolean ingestRunning;
@@ -608,7 +608,7 @@ private void exportButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
 
             KeywordSearchListsXML reader = KeywordSearchListsXML.getCurrent();
 
-            List<KeywordSearchList> toWrite = new ArrayList<KeywordSearchList>();
+            List<KeywordSearchListsAbstract.KeywordSearchList> toWrite = new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
             toWrite.add(reader.getList(currentKeywordList.getName()));
             final KeywordSearchListsXML exporter = new KeywordSearchListsXML(fileAbs);
             boolean written = exporter.saveLists(toWrite);
@@ -693,11 +693,11 @@ public void load() {
         // Implemented by parent panel
     }
     
-    KeywordSearchList getCurrentKeywordList() {
+    KeywordSearchListsAbstract.KeywordSearchList getCurrentKeywordList() {
         return currentKeywordList;
     }
     
-    void setCurrentKeywordList(KeywordSearchList list) {
+    void setCurrentKeywordList(KeywordSearchListsAbstract.KeywordSearchList list) {
         currentKeywordList = list;
     }
     
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java
index 0545b7c97f..4bb259b9b7 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestModule.java
@@ -101,7 +101,7 @@ int getTime() {
     private volatile boolean runSearcher = false; //whether to run searcher next time
     private List<Keyword> keywords; //keywords to search
     private List<String> keywordLists; // lists currently being searched
-    private Map<String, KeywordSearchList> keywordToList; //keyword to list name mapping
+    private Map<String, KeywordSearchListsAbstract.KeywordSearchList> keywordToList; //keyword to list name mapping
     private Timer commitTimer;
     private Timer searchTimer;
     private Indexer indexer;
@@ -380,7 +380,7 @@ public void init(IngestModuleInit initContext) {
 
         keywords = new ArrayList<Keyword>();
         keywordLists = new ArrayList<String>();
-        keywordToList = new HashMap<String, KeywordSearchList>();
+        keywordToList = new HashMap<String, KeywordSearchListsAbstract.KeywordSearchList>();
 
         initKeywords();
 
@@ -566,7 +566,7 @@ void addKeywordLists(List<String> listsToAdd) {
 
         StringBuilder sb = new StringBuilder();
 
-        for (KeywordSearchList list : loader.getListsL()) {
+        for (KeywordSearchListsAbstract.KeywordSearchList list : loader.getListsL()) {
             final String listName = list.getName();
             if (list.getUseForIngest() == true
                     || (listsToAdd != null && listsToAdd.contains(listName))) {
@@ -798,7 +798,7 @@ private final class Searcher extends SwingWorker<Object, Void> {
          */
         private List<Keyword> keywords; //keywords to search
         private List<String> keywordLists; // lists currently being searched
-        private Map<String, KeywordSearchList> keywordToList; //keyword to list name mapping
+        private Map<String, KeywordSearchListsAbstract.KeywordSearchList> keywordToList; //keyword to list name mapping
         private AggregateProgressHandle progressGroup;
         private final Logger logger = Logger.getLogger(Searcher.class.getName());
         private boolean finalRun = false;
@@ -806,7 +806,7 @@ private final class Searcher extends SwingWorker<Object, Void> {
         Searcher(List<String> keywordLists) {
             this.keywordLists = new ArrayList<String>(keywordLists);
             this.keywords = new ArrayList<Keyword>();
-            this.keywordToList = new HashMap<String, KeywordSearchList>();
+            this.keywordToList = new HashMap<String, KeywordSearchListsAbstract.KeywordSearchList>();
             //keywords are populated as searcher runs
         }
 
@@ -874,7 +874,7 @@ public boolean cancel() {
                     }
 
                     final String queryStr = keywordQuery.getQuery();
-                    final KeywordSearchList list = keywordToList.get(queryStr);
+                    final KeywordSearchListsAbstract.KeywordSearchList list = keywordToList.get(queryStr);
                     final String listName = list.getName();
 
                     //new subProgress will be active after the initial query
@@ -1110,7 +1110,7 @@ private void updateKeywords() {
             this.keywordToList.clear();
 
             for (String name : this.keywordLists) {
-                KeywordSearchList list = loader.getList(name);
+                KeywordSearchListsAbstract.KeywordSearchList list = loader.getList(name);
                 for (Keyword k : list.getKeywords()) {
                     this.keywords.add(k);
                     this.keywordToList.put(k.getQuery(), list);
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestSimplePanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestSimplePanel.java
index e3e91e5e57..35b9459405 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestSimplePanel.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchIngestSimplePanel.java
@@ -38,12 +38,12 @@ public class KeywordSearchIngestSimplePanel extends javax.swing.JPanel {
     private final static Logger logger = Logger.getLogger(KeywordSearchIngestSimplePanel.class.getName());
     public static final String PROP_OPTIONS = "Keyword Search_Options";
     private KeywordTableModel tableModel;
-    private List<KeywordSearchList> lists;
+    private List<KeywordSearchListsAbstract.KeywordSearchList> lists;
 
     /** Creates new form KeywordSearchIngestSimplePanel */
     public KeywordSearchIngestSimplePanel() {
         tableModel = new KeywordTableModel();
-        lists = new ArrayList<KeywordSearchList>();
+        lists = new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
         reloadLists();
         initComponents();
         customizeComponents();
@@ -222,7 +222,7 @@ public int getColumnCount() {
 
         @Override
         public Object getValueAt(int rowIndex, int columnIndex) {
-            KeywordSearchList list = KeywordSearchIngestSimplePanel.this.lists.get(rowIndex);
+            KeywordSearchListsAbstract.KeywordSearchList list = KeywordSearchIngestSimplePanel.this.lists.get(rowIndex);
             if(columnIndex == 0) {
                 return list.getUseForIngest();
             } else {
@@ -238,7 +238,7 @@ public boolean isCellEditable(int rowIndex, int columnIndex) {
         @Override
         public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
             
-            KeywordSearchList list = KeywordSearchIngestSimplePanel.this.lists.get(rowIndex);
+            KeywordSearchListsAbstract.KeywordSearchList list = KeywordSearchIngestSimplePanel.this.lists.get(rowIndex);
             if(columnIndex == 0){
                 KeywordSearchListsXML loader = KeywordSearchListsXML.getCurrent();
                 loader.addList(list.getName(), list.getKeywords(), (Boolean) aValue, false);
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsAbstract.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsAbstract.java
index de8e96dae8..23193818f1 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsAbstract.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsAbstract.java
@@ -1,526 +1,526 @@
-/*
- * Autopsy Forensic Browser
- * 
- * Copyright 2011 Basis Technology Corp.
- * Contact: carrier <at> sleuthkit <dot> org
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.sleuthkit.autopsy.keywordsearch;
-
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import org.sleuthkit.autopsy.coreutils.Logger;
-import org.sleuthkit.autopsy.coreutils.PlatformUtil;
-import org.sleuthkit.datamodel.BlackboardAttribute;
-
-/**
- * Keyword list saving, loading, and editing abstract class.
- */
-public abstract class KeywordSearchListsAbstract {
-
-    protected String filePath;
-    Map<String, KeywordSearchList> theLists; //the keyword data
-    static KeywordSearchListsXML currentInstance = null;
-    private static final String CUR_LISTS_FILE_NAME = "keywords.xml";
-    private static String CUR_LISTS_FILE = PlatformUtil.getUserConfigDirectory() + File.separator + CUR_LISTS_FILE_NAME;
-    protected static final Logger logger = Logger.getLogger(KeywordSearchListsAbstract.class.getName());
-    PropertyChangeSupport changeSupport;
-    protected List<String> lockedLists;
-
-    public KeywordSearchListsAbstract(String filePath) {
-        this.filePath = filePath;
-        theLists = new LinkedHashMap<String, KeywordSearchList>();
-        lockedLists = new ArrayList<String>();
-        changeSupport = new PropertyChangeSupport(this);
-    }
-
-    //property support
-    public enum ListsEvt {
-
-        LIST_ADDED, LIST_DELETED, LIST_UPDATED
-    };
-
-    /**
-     * get instance for managing the current keyword list of the application
-     */
-    static KeywordSearchListsXML getCurrent() {
-        if (currentInstance == null) {
-            currentInstance = new KeywordSearchListsXML(CUR_LISTS_FILE);
-            currentInstance.reload();
-        }
-        return currentInstance;
-    }
-
-    void addPropertyChangeListener(PropertyChangeListener l) {
-        changeSupport.addPropertyChangeListener(l);
-    }
-
-    private void prepopulateLists() {
-        if (! theLists.isEmpty()) {
-            return;
-        }
-        //phone number
-        List<Keyword> phones = new ArrayList<Keyword>();
-        phones.add(new Keyword("[(]{0,1}\\d\\d\\d[)]{0,1}[\\.-]\\d\\d\\d[\\.-]\\d\\d\\d\\d", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER));
-        //phones.add(new Keyword("\\d{8,10}", false));
-        //IP address
-        List<Keyword> ips = new ArrayList<Keyword>();
-        ips.add(new Keyword("(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS));
-        //email
-        List<Keyword> emails = new ArrayList<Keyword>();
-        emails.add(new Keyword("[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL));
-        //URL
-        List<Keyword> urls = new ArrayList<Keyword>();
-        //urls.add(new Keyword("http://|https://|^www\\.", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
-        urls.add(new Keyword("((((ht|f)tp(s?))\\://)|www\\.)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,5})(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\;\\?\\'\\\\+&amp;%\\$#\\=~_\\-]+))*", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
-
-        //urls.add(new Keyword("ssh://", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
-
-        //disable messages for harcoded/locked lists
-        String name;
-        
-        name = "Phone Numbers";
-        lockedLists.add(name);
-        addList(name, phones, false, false, true);
-        
-        name = "IP Addresses";
-        lockedLists.add(name);
-        addList(name, ips, false, false, true);
-        
-        name = "Email Addresses";
-        lockedLists.add(name);
-        addList(name, emails, true, false, true);
-        
-        name = "URLs";
-        lockedLists.add(name);
-        addList(name, urls, false, false, true);
-    }
-
-    /**
-     * load the file or create new
-     */
-    public void reload() {
-        boolean created = false;
-
-        //theLists.clear();
-        //populate only the first time
-        prepopulateLists();
-        
-        //reset all the lists other than locked lists (we don't save them to XML)
-        //we want to preserve state of locked lists
-        List<String> toClear = new ArrayList<String>();
-        for (String list : theLists.keySet()) {
-            if (theLists.get(list).isLocked() == false) {
-                toClear.add(list);
-            }
-        }
-        for (String clearList : toClear) {
-            theLists.remove(clearList);
-        } 
-        
-        if (!this.listFileExists()) {
-            //create new if it doesn't exist
-            save();
-            created = true;
-        }
-
-        //load, if fails to laod create new
-        if (!load() && !created) {
-            //create new if failed to load
-            save();
-        }
-
-
-    }
-
-    List<KeywordSearchList> getListsL() {
-        List<KeywordSearchList> ret = new ArrayList<KeywordSearchList>();
-        for (KeywordSearchList list : theLists.values()) {
-            ret.add(list);
-        }
-        return ret;
-    }
-
-    List<KeywordSearchList> getListsL(boolean locked) {
-        List<KeywordSearchList> ret = new ArrayList<KeywordSearchList>();
-        for (KeywordSearchList list : theLists.values()) {
-            if (list.isLocked().equals(locked)) {
-                ret.add(list);
-            }
-        }
-        return ret;
-    }
-
-    /**
-     * Get list names of all loaded keyword list names
-     *
-     * @return List of keyword list names
-     */
-    List<String> getListNames() {
-        return new ArrayList<String>(theLists.keySet());
-    }
-
-    /**
-     * Get list names of all locked or unlocked loaded keyword list names
-     *
-     * @param locked true if look for locked lists, false otherwise
-     * @return List of keyword list names
-     */
-    List<String> getListNames(boolean locked) {
-        ArrayList<String> lists = new ArrayList<String>();
-        for (String listName : theLists.keySet()) {
-            KeywordSearchList list = theLists.get(listName);
-            if (locked == list.isLocked()) {
-                lists.add(listName);
-            }
-        }
-
-        return lists;
-    }
-
-    /**
-     * return first list that contains the keyword
-     *
-     * @param keyword
-     * @return found list or null
-     */
-    KeywordSearchList getListWithKeyword(Keyword keyword) {
-        KeywordSearchList found = null;
-        for (KeywordSearchList list : theLists.values()) {
-            if (list.hasKeyword(keyword)) {
-                found = list;
-                break;
-            }
-        }
-        return found;
-    }
-
-    /**
-     * return first list that contains the keyword
-     *
-     * @param keyword
-     * @return found list or null
-     */
-    KeywordSearchList getListWithKeyword(String keyword) {
-        KeywordSearchList found = null;
-        for (KeywordSearchList list : theLists.values()) {
-            if (list.hasKeyword(keyword)) {
-                found = list;
-                break;
-            }
-        }
-        return found;
-    }
-
-    /**
-     * get number of lists currently stored
-     *
-     * @return number of lists currently stored
-     */
-    int getNumberLists() {
-        return theLists.size();
-    }
-
-    /**
-     * get number of unlocked or locked lists currently stored
-     *
-     * @param locked true if look for locked lists, false otherwise
-     * @return number of unlocked lists currently stored
-     */
-    int getNumberLists(boolean locked) {
-        int numLists = 0;
-        for (String listName : theLists.keySet()) {
-            KeywordSearchList list = theLists.get(listName);
-            if (locked == list.isLocked()) {
-                ++numLists;
-            }
-        }
-        return numLists;
-    }
-
-    /**
-     * get list by name or null
-     *
-     * @param name id of the list
-     * @return keyword list representation
-     */
-    KeywordSearchList getList(String name) {
-        return theLists.get(name);
-    }
-
-    /**
-     * check if list with given name id exists
-     *
-     * @param name id to check
-     * @return true if list already exists or false otherwise
-     */
-    boolean listExists(String name) {
-        return getList(name) != null;
-    }
-
-    /**
-     * adds the new word list using name id replacing old one if exists with the
-     * same name
-     *
-     * @param name the name of the new list or list to replace
-     * @param newList list of keywords
-     * @param useForIngest should this list be used for ingest
-     * @return true if old list was replaced
-     */
-    boolean addList(String name, List<Keyword> newList, boolean useForIngest, boolean ingestMessages, boolean locked) {
-        boolean replaced = false;
-        KeywordSearchList curList = getList(name);
-        final Date now = new Date();
-
-        if (curList == null) {
-            theLists.put(name, new KeywordSearchList(name, now, now, useForIngest, ingestMessages, newList, locked));
-//            if (!locked) {
-//                save();
-//            }
-            changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, name);
-        } else {
-            theLists.put(name, new KeywordSearchList(name, curList.getDateCreated(), now, useForIngest, ingestMessages, newList, locked));
-//            if (!locked) {
-//                save();
-//            }
-            replaced = true;
-            changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, name);
-        }
-
-        return replaced;
-    }
-
-    boolean addList(String name, List<Keyword> newList, boolean useForIngest, boolean ingestMessages) {
-        //make sure that the list is readded as a locked/built in list 
-        boolean isLocked = this.lockedLists.contains(name);
-        return addList(name, newList, useForIngest, ingestMessages, isLocked);
-    }
-
-    boolean addList(String name, List<Keyword> newList) {
-        boolean isLocked = this.lockedLists.contains(name);
-        return addList(name, newList, true, isLocked);
-    }
-
-    boolean addList(KeywordSearchList list) {
-        return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(), list.isLocked());
-    }
-
-    /**
-     * save multiple lists
-     *
-     * @param lists
-     * @return
-     */
-    boolean saveLists(List<KeywordSearchList> lists) {
-        int oldSize = this.getNumberLists();
-
-        List<KeywordSearchList> overwritten = new ArrayList<KeywordSearchList>();
-        List<KeywordSearchList> newLists = new ArrayList<KeywordSearchList>();
-        for (KeywordSearchList list : lists) {
-            if (this.listExists(list.getName())) {
-                overwritten.add(list);
-            } else {
-                newLists.add(list);
-            }
-            theLists.put(list.getName(), list);
-        }
-        boolean saved = save(true);
-        if (saved) {
-            for (KeywordSearchList list : newLists) {
-                changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
-            }
-            for (KeywordSearchList over : overwritten) {
-                changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
-            }
-        }
-
-        return saved;
-    }
-
-    /**
-     * write out multiple lists
-     *
-     * @param lists
-     * @return
-     */
-    boolean writeLists(List<KeywordSearchList> lists) {
-        int oldSize = this.getNumberLists();
-
-        List<KeywordSearchList> overwritten = new ArrayList<KeywordSearchList>();
-        List<KeywordSearchList> newLists = new ArrayList<KeywordSearchList>();
-        for (KeywordSearchList list : lists) {
-            if (this.listExists(list.getName())) {
-                overwritten.add(list);
-            } else {
-                newLists.add(list);
-            }
-            theLists.put(list.getName(), list);
-        }
-        //boolean saved = save();
-
-        for (KeywordSearchList list : newLists) {
-            changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
-        }
-        for (KeywordSearchList over : overwritten) {
-            changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
-        }
-
-        return true;
-    }
-
-    /**
-     * delete list if exists and save new list
-     *
-     * @param name of list to delete
-     * @return true if deleted
-     */
-    boolean deleteList(String name) {
-        boolean deleted = false;
-        KeywordSearchList delList = getList(name);
-        if (delList != null && !delList.isLocked()) {
-            theLists.remove(name);
-            //deleted = save();
-        }
-        changeSupport.firePropertyChange(ListsEvt.LIST_DELETED.toString(), null, name);
-        return true;
-
-    }
-
-    /**
-     * writes out current list replacing the last lists file
-     */
-    public abstract boolean save();
-    
-    /**
-     * writes out current list replacing the last lists file
-     * @param isExport true is this save operation is an export and not a 'Save
-     * As'
-     */
-    public abstract boolean save(boolean isExport);
-
-    /**
-     * load and parse List, then dispose
-     */
-    public abstract boolean load();
-
-    private boolean listFileExists() {
-        File f = new File(filePath);
-        return f.exists() && f.canRead() && f.canWrite();
-    }
-}
-
-/**
- * a representation of a single keyword list created or loaded
- */
-class KeywordSearchList {
-
-    private String name;
-    private Date created;
-    private Date modified;
-    private Boolean useForIngest;
-    private Boolean ingestMessages;
-    private List<Keyword> keywords;
-    private Boolean locked;
-
-    KeywordSearchList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages, List<Keyword> keywords, boolean locked) {
-        this.name = name;
-        this.created = created;
-        this.modified = modified;
-        this.useForIngest = useForIngest;
-        this.ingestMessages = ingestMessages;
-        this.keywords = keywords;
-        this.locked = locked;
-    }
-
-    KeywordSearchList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages, List<Keyword> keywords) {
-        this(name, created, modified, useForIngest, ingestMessages, keywords, false);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
-        }
-        final KeywordSearchList other = (KeywordSearchList) obj;
-        if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
-            return false;
-        }
-        return true;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 5;
-        return hash;
-    }
-
-    String getName() {
-        return name;
-    }
-
-    Date getDateCreated() {
-        return created;
-    }
-
-    Date getDateModified() {
-        return modified;
-    }
-
-    Boolean getUseForIngest() {
-        return useForIngest;
-    }
-
-    void setUseForIngest(boolean use) {
-        this.useForIngest = use;
-    }
-
-    Boolean getIngestMessages() {
-        return ingestMessages;
-    }
-
-    void setIngestMessages(boolean ingestMessages) {
-        this.ingestMessages = ingestMessages;
-    }
-
-    List<Keyword> getKeywords() {
-        return keywords;
-    }
-
-    boolean hasKeyword(Keyword keyword) {
-        return keywords.contains(keyword);
-    }
-
-    boolean hasKeyword(String keyword) {
-        //note, this ignores isLiteral
-        for (Keyword k : keywords) {
-            if (k.getQuery().equals(keyword)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    Boolean isLocked() {
-        return locked;
-    }
+/*
+ * Autopsy Forensic Browser
+ * 
+ * Copyright 2011 Basis Technology Corp.
+ * Contact: carrier <at> sleuthkit <dot> org
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.sleuthkit.autopsy.keywordsearch;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.sleuthkit.autopsy.coreutils.Logger;
+import org.sleuthkit.autopsy.coreutils.PlatformUtil;
+import org.sleuthkit.datamodel.BlackboardAttribute;
+
+/**
+ * Keyword list saving, loading, and editing abstract class.
+ */
+public abstract class KeywordSearchListsAbstract {
+
+    protected String filePath;
+    public Map<String, KeywordSearchList> theLists; //the keyword data
+    static KeywordSearchListsXML currentInstance = null;
+    private static final String CUR_LISTS_FILE_NAME = "keywords.xml";
+    private static String CUR_LISTS_FILE = PlatformUtil.getUserConfigDirectory() + File.separator + CUR_LISTS_FILE_NAME;
+    protected static final Logger logger = Logger.getLogger(KeywordSearchListsAbstract.class.getName());
+    PropertyChangeSupport changeSupport;
+    protected List<String> lockedLists;
+
+    public KeywordSearchListsAbstract(String filePath) {
+        this.filePath = filePath;
+        theLists = new LinkedHashMap<String, KeywordSearchList>();
+        lockedLists = new ArrayList<String>();
+        changeSupport = new PropertyChangeSupport(this);
+    }
+
+    //property support
+    public enum ListsEvt {
+
+        LIST_ADDED, LIST_DELETED, LIST_UPDATED
+    };
+
+    /**
+     * get instance for managing the current keyword list of the application
+     */
+    public static KeywordSearchListsXML getCurrent() {
+        if (currentInstance == null) {
+            currentInstance = new KeywordSearchListsXML(CUR_LISTS_FILE);
+            currentInstance.reload();
+        }
+        return currentInstance;
+    }
+
+    void addPropertyChangeListener(PropertyChangeListener l) {
+        changeSupport.addPropertyChangeListener(l);
+    }
+
+    private void prepopulateLists() {
+        if (! theLists.isEmpty()) {
+            return;
+        }
+        //phone number
+        List<Keyword> phones = new ArrayList<Keyword>();
+        phones.add(new Keyword("[(]{0,1}\\d\\d\\d[)]{0,1}[\\.-]\\d\\d\\d[\\.-]\\d\\d\\d\\d", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER));
+        //phones.add(new Keyword("\\d{8,10}", false));
+        //IP address
+        List<Keyword> ips = new ArrayList<Keyword>();
+        ips.add(new Keyword("(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_IP_ADDRESS));
+        //email
+        List<Keyword> emails = new ArrayList<Keyword>();
+        emails.add(new Keyword("[A-Z0-9._%-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_EMAIL));
+        //URL
+        List<Keyword> urls = new ArrayList<Keyword>();
+        //urls.add(new Keyword("http://|https://|^www\\.", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
+        urls.add(new Keyword("((((ht|f)tp(s?))\\://)|www\\.)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,5})(\\:[0-9]+)*(/($|[a-zA-Z0-9\\.\\,\\;\\?\\'\\\\+&amp;%\\$#\\=~_\\-]+))*", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
+
+        //urls.add(new Keyword("ssh://", false, BlackboardAttribute.ATTRIBUTE_TYPE.TSK_URL));
+
+        //disable messages for harcoded/locked lists
+        String name;
+        
+        name = "Phone Numbers";
+        lockedLists.add(name);
+        addList(name, phones, false, false, true);
+        
+        name = "IP Addresses";
+        lockedLists.add(name);
+        addList(name, ips, false, false, true);
+        
+        name = "Email Addresses";
+        lockedLists.add(name);
+        addList(name, emails, true, false, true);
+        
+        name = "URLs";
+        lockedLists.add(name);
+        addList(name, urls, false, false, true);
+    }
+
+    /**
+     * load the file or create new
+     */
+    public void reload() {
+        boolean created = false;
+
+        //theLists.clear();
+        //populate only the first time
+        prepopulateLists();
+        
+        //reset all the lists other than locked lists (we don't save them to XML)
+        //we want to preserve state of locked lists
+        List<String> toClear = new ArrayList<String>();
+        for (String list : theLists.keySet()) {
+            if (theLists.get(list).isLocked() == false) {
+                toClear.add(list);
+            }
+        }
+        for (String clearList : toClear) {
+            theLists.remove(clearList);
+        } 
+        
+        if (!this.listFileExists()) {
+            //create new if it doesn't exist
+            save();
+            created = true;
+        }
+
+        //load, if fails to laod create new
+        if (!load() && !created) {
+            //create new if failed to load
+            save();
+        }
+
+
+    }
+
+    List<KeywordSearchList> getListsL() {
+        List<KeywordSearchList> ret = new ArrayList<KeywordSearchList>();
+        for (KeywordSearchList list : theLists.values()) {
+            ret.add(list);
+        }
+        return ret;
+    }
+
+    List<KeywordSearchList> getListsL(boolean locked) {
+        List<KeywordSearchList> ret = new ArrayList<KeywordSearchList>();
+        for (KeywordSearchList list : theLists.values()) {
+            if (list.isLocked().equals(locked)) {
+                ret.add(list);
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Get list names of all loaded keyword list names
+     *
+     * @return List of keyword list names
+     */
+    List<String> getListNames() {
+        return new ArrayList<String>(theLists.keySet());
+    }
+
+    /**
+     * Get list names of all locked or unlocked loaded keyword list names
+     *
+     * @param locked true if look for locked lists, false otherwise
+     * @return List of keyword list names
+     */
+    List<String> getListNames(boolean locked) {
+        ArrayList<String> lists = new ArrayList<String>();
+        for (String listName : theLists.keySet()) {
+            KeywordSearchList list = theLists.get(listName);
+            if (locked == list.isLocked()) {
+                lists.add(listName);
+            }
+        }
+
+        return lists;
+    }
+
+    /**
+     * return first list that contains the keyword
+     *
+     * @param keyword
+     * @return found list or null
+     */
+    KeywordSearchList getListWithKeyword(Keyword keyword) {
+        KeywordSearchList found = null;
+        for (KeywordSearchList list : theLists.values()) {
+            if (list.hasKeyword(keyword)) {
+                found = list;
+                break;
+            }
+        }
+        return found;
+    }
+
+    /**
+     * return first list that contains the keyword
+     *
+     * @param keyword
+     * @return found list or null
+     */
+    KeywordSearchList getListWithKeyword(String keyword) {
+        KeywordSearchList found = null;
+        for (KeywordSearchList list : theLists.values()) {
+            if (list.hasKeyword(keyword)) {
+                found = list;
+                break;
+            }
+        }
+        return found;
+    }
+
+    /**
+     * get number of lists currently stored
+     *
+     * @return number of lists currently stored
+     */
+    int getNumberLists() {
+        return theLists.size();
+    }
+
+    /**
+     * get number of unlocked or locked lists currently stored
+     *
+     * @param locked true if look for locked lists, false otherwise
+     * @return number of unlocked lists currently stored
+     */
+    int getNumberLists(boolean locked) {
+        int numLists = 0;
+        for (String listName : theLists.keySet()) {
+            KeywordSearchList list = theLists.get(listName);
+            if (locked == list.isLocked()) {
+                ++numLists;
+            }
+        }
+        return numLists;
+    }
+
+    /**
+     * get list by name or null
+     *
+     * @param name id of the list
+     * @return keyword list representation
+     */
+    KeywordSearchList getList(String name) {
+        return theLists.get(name);
+    }
+
+    /**
+     * check if list with given name id exists
+     *
+     * @param name id to check
+     * @return true if list already exists or false otherwise
+     */
+    boolean listExists(String name) {
+        return getList(name) != null;
+    }
+
+    /**
+     * adds the new word list using name id replacing old one if exists with the
+     * same name
+     *
+     * @param name the name of the new list or list to replace
+     * @param newList list of keywords
+     * @param useForIngest should this list be used for ingest
+     * @return true if old list was replaced
+     */
+    boolean addList(String name, List<Keyword> newList, boolean useForIngest, boolean ingestMessages, boolean locked) {
+        boolean replaced = false;
+        KeywordSearchList curList = getList(name);
+        final Date now = new Date();
+
+        if (curList == null) {
+            theLists.put(name, new KeywordSearchList(name, now, now, useForIngest, ingestMessages, newList, locked));
+//            if (!locked) {
+//                save();
+//            }
+            changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, name);
+        } else {
+            theLists.put(name, new KeywordSearchList(name, curList.getDateCreated(), now, useForIngest, ingestMessages, newList, locked));
+//            if (!locked) {
+//                save();
+//            }
+            replaced = true;
+            changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, name);
+        }
+
+        return replaced;
+    }
+
+    boolean addList(String name, List<Keyword> newList, boolean useForIngest, boolean ingestMessages) {
+        //make sure that the list is readded as a locked/built in list 
+        boolean isLocked = this.lockedLists.contains(name);
+        return addList(name, newList, useForIngest, ingestMessages, isLocked);
+    }
+
+    boolean addList(String name, List<Keyword> newList) {
+        boolean isLocked = this.lockedLists.contains(name);
+        return addList(name, newList, true, isLocked);
+    }
+
+    boolean addList(KeywordSearchList list) {
+        return addList(list.getName(), list.getKeywords(), list.getUseForIngest(), list.getIngestMessages(), list.isLocked());
+    }
+
+    /**
+     * save multiple lists
+     *
+     * @param lists
+     * @return
+     */
+    boolean saveLists(List<KeywordSearchList> lists) {
+        int oldSize = this.getNumberLists();
+
+        List<KeywordSearchList> overwritten = new ArrayList<KeywordSearchList>();
+        List<KeywordSearchList> newLists = new ArrayList<KeywordSearchList>();
+        for (KeywordSearchList list : lists) {
+            if (this.listExists(list.getName())) {
+                overwritten.add(list);
+            } else {
+                newLists.add(list);
+            }
+            theLists.put(list.getName(), list);
+        }
+        boolean saved = save(true);
+        if (saved) {
+            for (KeywordSearchList list : newLists) {
+                changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
+            }
+            for (KeywordSearchList over : overwritten) {
+                changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
+            }
+        }
+
+        return saved;
+    }
+
+    /**
+     * write out multiple lists
+     *
+     * @param lists
+     * @return
+     */
+    boolean writeLists(List<KeywordSearchList> lists) {
+        int oldSize = this.getNumberLists();
+
+        List<KeywordSearchList> overwritten = new ArrayList<KeywordSearchList>();
+        List<KeywordSearchList> newLists = new ArrayList<KeywordSearchList>();
+        for (KeywordSearchList list : lists) {
+            if (this.listExists(list.getName())) {
+                overwritten.add(list);
+            } else {
+                newLists.add(list);
+            }
+            theLists.put(list.getName(), list);
+        }
+        //boolean saved = save();
+
+        for (KeywordSearchList list : newLists) {
+            changeSupport.firePropertyChange(ListsEvt.LIST_ADDED.toString(), null, list.getName());
+        }
+        for (KeywordSearchList over : overwritten) {
+            changeSupport.firePropertyChange(ListsEvt.LIST_UPDATED.toString(), null, over.getName());
+        }
+
+        return true;
+    }
+
+    /**
+     * delete list if exists and save new list
+     *
+     * @param name of list to delete
+     * @return true if deleted
+     */
+    boolean deleteList(String name) {
+        boolean deleted = false;
+        KeywordSearchList delList = getList(name);
+        if (delList != null && !delList.isLocked()) {
+            theLists.remove(name);
+            //deleted = save();
+        }
+        changeSupport.firePropertyChange(ListsEvt.LIST_DELETED.toString(), null, name);
+        return true;
+
+    }
+
+    /**
+     * writes out current list replacing the last lists file
+     */
+    public abstract boolean save();
+    
+    /**
+     * writes out current list replacing the last lists file
+     * @param isExport true is this save operation is an export and not a 'Save
+     * As'
+     */
+    public abstract boolean save(boolean isExport);
+
+    /**
+     * load and parse List, then dispose
+     */
+    public abstract boolean load();
+
+    private boolean listFileExists() {
+        File f = new File(filePath);
+        return f.exists() && f.canRead() && f.canWrite();
+    }
+    
+    /**
+     * a representation of a single keyword list created or loaded
+     */
+    public class KeywordSearchList {
+
+        private String name;
+        private Date created;
+        private Date modified;
+        private Boolean useForIngest;
+        private Boolean ingestMessages;
+        private List<Keyword> keywords;
+        private Boolean locked;
+
+        KeywordSearchList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages, List<Keyword> keywords, boolean locked) {
+            this.name = name;
+            this.created = created;
+            this.modified = modified;
+            this.useForIngest = useForIngest;
+            this.ingestMessages = ingestMessages;
+            this.keywords = keywords;
+            this.locked = locked;
+        }
+
+        KeywordSearchList(String name, Date created, Date modified, Boolean useForIngest, Boolean ingestMessages, List<Keyword> keywords) {
+            this(name, created, modified, useForIngest, ingestMessages, keywords, false);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final KeywordSearchList other = (KeywordSearchList) obj;
+            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int hash = 5;
+            return hash;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public Date getDateCreated() {
+            return created;
+        }
+
+        public Date getDateModified() {
+            return modified;
+        }
+
+        public Boolean getUseForIngest() {
+            return useForIngest;
+        }
+
+        public void setUseForIngest(boolean use) {
+            this.useForIngest = use;
+        }
+
+        public Boolean getIngestMessages() {
+            return ingestMessages;
+        }
+
+        public void setIngestMessages(boolean ingestMessages) {
+            this.ingestMessages = ingestMessages;
+        }
+
+        public List<Keyword> getKeywords() {
+            return keywords;
+        }
+
+        public boolean hasKeyword(Keyword keyword) {
+            return keywords.contains(keyword);
+        }
+
+        public boolean hasKeyword(String keyword) {
+            //note, this ignores isLiteral
+            for (Keyword k : keywords) {
+                if (k.getQuery().equals(keyword)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public Boolean isLocked() {
+            return locked;
+        }
+    }
 }
\ No newline at end of file
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.form b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.form
index f3b8306b06..cb2629ae11 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.form
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.form
@@ -37,7 +37,7 @@
                               <Component id="importButton" min="-2" pref="126" max="-2" attributes="0"/>
                           </Group>
                       </Group>
-                      <EmptySpace min="0" pref="4" max="32767" attributes="0"/>
+                      <EmptySpace min="0" pref="0" max="32767" attributes="0"/>
                   </Group>
               </Group>
               <EmptySpace max="-2" attributes="0"/>
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java
index ae73ef504e..3e64ad20d3 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsManagementPanel.java
@@ -243,12 +243,12 @@ private void importButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-
                 return;
             }
 
-            List<KeywordSearchList> toImport = reader.getListsL();
-            List<KeywordSearchList> toImportConfirmed = new ArrayList<KeywordSearchList>();
+            List<KeywordSearchListsAbstract.KeywordSearchList> toImport = reader.getListsL();
+            List<KeywordSearchListsAbstract.KeywordSearchList> toImportConfirmed = new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
 
             final KeywordSearchListsXML writer = KeywordSearchListsXML.getCurrent();
 
-            for (KeywordSearchList list : toImport) {
+            for (KeywordSearchListsAbstract.KeywordSearchList list : toImport) {
                 //check name collisions
                 if (writer.listExists(list.getName())) {
                     Object[] options = {"Yes, overwrite",
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java
index bf27605fcd..e124ef44e2 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchListsViewerPanel.java
@@ -105,7 +105,7 @@ public void valueChanged(ListSelectionEvent e) {
                 ListSelectionModel listSelectionModel = (ListSelectionModel) e.getSource();
                 if (!listSelectionModel.isSelectionEmpty()) {
                     int index = listSelectionModel.getMinSelectionIndex();
-                    KeywordSearchList list = listsTableModel.getListAt(index);
+                    KeywordSearchListsAbstract.KeywordSearchList list = listsTableModel.getListAt(index);
                     keywordsTableModel.resync(list);
                 } else {
                     keywordsTableModel.deleteAll();
@@ -307,13 +307,13 @@ private void searchAction(ActionEvent e) {
     @Override
     public List<Keyword> getQueryList() {
         List<Keyword> ret = new ArrayList<Keyword>();
-        for (KeywordSearchList list : getSelectedLists()) {
+        for (KeywordSearchListsAbstract.KeywordSearchList list : getSelectedLists()) {
             ret.addAll(list.getKeywords());
         }
         return ret;
     }
 
-    private List<KeywordSearchList> getSelectedLists() {
+    private List<KeywordSearchListsAbstract.KeywordSearchList> getSelectedLists() {
         return listsTableModel.getSelectedListsL();
     }
 
@@ -427,7 +427,7 @@ List<String> getAllLists() {
             return ret;
         }
 
-        KeywordSearchList getListAt(int rowIndex) {
+        KeywordSearchListsAbstract.KeywordSearchList getListAt(int rowIndex) {
             return listsHandle.getList((String) getValueAt(rowIndex, 1));
         }
 
@@ -441,8 +441,8 @@ List<String> getSelectedLists() {
             return ret;
         }
 
-        List<KeywordSearchList> getSelectedListsL() {
-            List<KeywordSearchList> ret = new ArrayList<KeywordSearchList>();
+        List<KeywordSearchListsAbstract.KeywordSearchList> getSelectedListsL() {
+            List<KeywordSearchListsAbstract.KeywordSearchList> ret = new ArrayList<KeywordSearchListsAbstract.KeywordSearchList>();
             for (String s : getSelectedLists()) {
                 ret.add(listsHandle.getList(s));
             }
@@ -462,8 +462,8 @@ void resync() {
         }
 
         //add lists to the model
-        private void addLists(List<KeywordSearchList> lists) {
-            for (KeywordSearchList list : lists) {
+        private void addLists(List<KeywordSearchListsAbstract.KeywordSearchList> lists) {
+            for (KeywordSearchListsAbstract.KeywordSearchList list : lists) {
                 if (!listExists(list.getName())) {
                     listData.add(new ListTableEntry(list, ingestRunning));
                 }
@@ -476,7 +476,7 @@ private class ListTableEntry implements Comparable<ListTableEntry> {
             String name;
             Boolean selected;
 
-            ListTableEntry(KeywordSearchList list, boolean ingestRunning) {
+            ListTableEntry(KeywordSearchListsAbstract.KeywordSearchList list, boolean ingestRunning) {
                 this.name = list.getName();
                 if (ingestRunning) {
                     this.selected = list.getUseForIngest();
@@ -558,7 +558,7 @@ public Class<?> getColumnClass(int c) {
             return getValueAt(0, c).getClass();
         }
 
-        void resync(KeywordSearchList list) {
+        void resync(KeywordSearchListsAbstract.KeywordSearchList list) {
             listData.clear();
             for (Keyword k : list.getKeywords()) {
                 listData.add(new KeywordTableEntry(k));
diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java
index 634ac92402..36975c9cda 100644
--- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java
+++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/KeywordSearchResultFactory.java
@@ -236,7 +236,7 @@ protected boolean createKeys(List<KeyValueQuery> toPopulate) {
 
             //get listname
             String listName = "";
-            KeywordSearchList list = KeywordSearchListsXML.getCurrent().getListWithKeyword(tcq.getQueryString());
+            KeywordSearchListsAbstract.KeywordSearchList list = KeywordSearchListsXML.getCurrent().getListWithKeyword(tcq.getQueryString());
             if (list != null) {
                 listName = list.getName();
             }
diff --git a/Testing/nbproject/project.xml b/Testing/nbproject/project.xml
index 2de5ca7b67..6b7be2ee79 100644
--- a/Testing/nbproject/project.xml
+++ b/Testing/nbproject/project.xml
@@ -15,6 +15,15 @@
                         <specification-version>5.0</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    <code-name-base>org.sleuthkit.autopsy.keywordsearch</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>5</release-version>
+                        <specification-version>3.0</specification-version>
+                    </run-dependency>
+                </dependency>
             </module-dependencies>
             <test-dependencies>
                 <test-type>
diff --git a/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java b/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java
index 3746f52abb..33a5480573 100644
--- a/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java
+++ b/Testing/test/qa-functional/src/org/sleuthkit/autopsy/testing/RegressionTest.java
@@ -52,6 +52,7 @@
 import org.netbeans.jemmy.operators.JTextFieldOperator;
 import org.netbeans.junit.NbModuleSuite;
 import org.sleuthkit.autopsy.ingest.IngestManager;
+import org.sleuthkit.autopsy.keywordsearch.*;
 /**
  * This test expects the following system properties to be set:
  * img_path: The fully qualified path to the image file (if split, the first file)
@@ -207,6 +208,8 @@ public void testConfigureSearch() {
         logger.info("Search Configure");
         JDialog jd = JDialogOperator.waitJDialog("Advanced Keyword Search Configuration", false, false);
         JDialogOperator jdo = new JDialogOperator(jd);
+        KeywordSearchListsXML curr = KeywordSearchListsXML.getCurrent();
+        curr.theLists.get("URLs").setUseForIngest(true);
         String words = System.getProperty("keyword_path");
         JButtonOperator jbo0 = new JButtonOperator(jdo, "Import List", 0);
         jbo0.pushNoBlock();
-- 
GitLab