diff --git a/import/SolrMarc.jar b/import/SolrMarc.jar
index 6c6a47ce850bcbd2d0d68e293201834e3714b112..22e71ecd16413b66aebda8094713632c8a9fe761 100644
Binary files a/import/SolrMarc.jar and b/import/SolrMarc.jar differ
diff --git a/import/VuFindIndexer.jar b/import/VuFindIndexer.jar
index fc61f4468d31e8259277816d84f918982eda1bd8..5a3e93b1df666922af46a9439dcda116fc43f735 100644
Binary files a/import/VuFindIndexer.jar and b/import/VuFindIndexer.jar differ
diff --git a/import/bin/to_ncr b/import/bin/to_ncr
new file mode 100644
index 0000000000000000000000000000000000000000..4e05df00d059365aa3039a75c6db3a00673a21e2
--- /dev/null
+++ b/import/bin/to_ncr
@@ -0,0 +1,28 @@
+#! /bin/bash
+# to_marc8.sh
+# Diagnostic program to display marc records.
+# $Id: to_marc8.sh 
+
+E_BADARGS=65
+
+scriptdir=$( (cd -P $(dirname $0) && pwd) )
+if ! [ -e $scriptdir/SolrMarc.jar ] 
+then
+  scriptdir=$( (cd -P $(dirname $0)/.. && pwd) )
+fi
+
+if ! [ -p /dev/stdin ]
+then  
+  if [ $# -eq 0 ]
+  then
+    echo "    Usage: `basename $0` [config.properties] ./path/to/marc.mrc "
+    echo "      Note that if the config.properties file is not specified the Jarfile will be searched for"
+    echo "      a file whose name ends with \"config.properties\""
+    exit $E_BADARGS
+  fi
+fi
+
+java -Dsolrmarc.main.class="org.solrmarc.marc.MarcPrinter" -jar $scriptdir/SolrMarc.jar untranslateNCR $1 $2 
+
+exit 0
+
diff --git a/import/bin/to_ncr.bat b/import/bin/to_ncr.bat
new file mode 100644
index 0000000000000000000000000000000000000000..3c59e9e545ea65b88d1ef9290eb2c8593a08bb75
--- /dev/null
+++ b/import/bin/to_ncr.bat
@@ -0,0 +1,18 @@
+@echo off
+:: printrecord.bat
+:: Diagnostic program to display marc records.
+:: $Id: printrecord.bat
+setlocal
+::Get the current batch file's short path
+for %%x in (%~f0) do set scriptdir=%%~dpsx
+for %%x in (%scriptdir%) do set scriptdir=%%~dpsx
+::echo BatchPath = %scriptdir%
+
+if EXIST %scriptdir%SolrMarc.jar goto doit
+pushd %scriptdir%..
+for %%x in (%CD%) do set scriptdir=%%~sx\
+popd
+
+:doit
+
+java -Dsolrmarc.main.class="org.solrmarc.marc.MarcPrinter" -jar %scriptdir%SolrMarc.jar untranslateNCR %1 %2 %3
diff --git a/import/bin/to_utf8 b/import/bin/to_utf8
new file mode 100644
index 0000000000000000000000000000000000000000..7b41ffb1c518d1b5bc478f6c33676d385a7230ef
--- /dev/null
+++ b/import/bin/to_utf8
@@ -0,0 +1,28 @@
+#! /bin/bash
+# to_marc8.sh
+# Diagnostic program to display marc records.
+# $Id: to_marc8.sh 
+
+E_BADARGS=65
+
+scriptdir=$( (cd -P $(dirname $0) && pwd) )
+if ! [ -e $scriptdir/SolrMarc.jar ] 
+then
+  scriptdir=$( (cd -P $(dirname $0)/.. && pwd) )
+fi
+
+if ! [ -p /dev/stdin ]
+then  
+  if [ $# -eq 0 ]
+  then
+    echo "    Usage: `basename $0` [config.properties] ./path/to/marc.mrc "
+    echo "      Note that if the config.properties file is not specified the Jarfile will be searched for"
+    echo "      a file whose name ends with \"config.properties\""
+    exit $E_BADARGS
+  fi
+fi
+
+java -Dsolrmarc.main.class="org.solrmarc.marc.MarcPrinter" -jar $scriptdir/SolrMarc.jar translate $1 $2 
+
+exit 0
+
diff --git a/import/bin/to_utf8.bat b/import/bin/to_utf8.bat
new file mode 100644
index 0000000000000000000000000000000000000000..80e7ee69d9a9db33f05da3bb1e55771cb65c2489
--- /dev/null
+++ b/import/bin/to_utf8.bat
@@ -0,0 +1,18 @@
+@echo off
+:: printrecord.bat
+:: Diagnostic program to display marc records.
+:: $Id: printrecord.bat
+setlocal
+::Get the current batch file's short path
+for %%x in (%~f0) do set scriptdir=%%~dpsx
+for %%x in (%scriptdir%) do set scriptdir=%%~dpsx
+::echo BatchPath = %scriptdir%
+
+if EXIST %scriptdir%SolrMarc.jar goto doit
+pushd %scriptdir%..
+for %%x in (%CD%) do set scriptdir=%%~sx\
+popd
+
+:doit
+
+java -Dsolrmarc.main.class="org.solrmarc.marc.MarcPrinter" -jar %scriptdir%SolrMarc.jar translate %1 %2 %3
diff --git a/import/index_scripts/callnumber.bsh b/import/index_scripts/callnumber.bsh
index adefd8dfbcb98ac3748bf30959660ef4ef0d5f5b..860b6d882983b4b995d3b0bdeee71bef7a63b7b3 100644
--- a/import/index_scripts/callnumber.bsh
+++ b/import/index_scripts/callnumber.bsh
@@ -6,131 +6,125 @@
  * it will be applied during indexing.
  */
 import org.marc4j.marc.Record;
-import org.solrmarc.tools.CallNumUtils;
 
 // define the base level indexer so that its methods can be called from the script.
 // note that the SolrIndexer code will set this value before the script methods are called.
 org.solrmarc.index.SolrIndexer indexer = null;
 
 /**
- * Extract the call number label from a record
- * @param record
- * @return Call number label
- */
+* Extract the call number label from a record
+* @param record
+* @return Call number label
+*/
 public String getFullCallNumber(Record record) {
 
-    return(getFullCallNumber(record, "099ab:090ab:050ab"));
+return(getFullCallNumber(record, "099ab:090ab:050ab"));
 }
 
 /**
- * Extract the call number label from a record
- * @param record
- * @return Call number label
- */
+* Extract the call number label from a record
+* @param record
+* @return Call number label
+*/
 public String getFullCallNumber(Record record, String fieldSpec) {
 
-    String val = indexer.getFirstFieldVal(record, fieldSpec);
+String val = indexer.getFirstFieldVal(record, fieldSpec);
 
-    if (val != null) {
-        return val.toUpperCase().replaceAll(" ", "");
-    } else {
-        return val;
-    }
+if (val != null) {
+return val.toUpperCase().replaceAll(" ", "");
+} else {
+return val;
+}
 }
 
 /**
- * Extract the call number label from a record
- * @param record
- * @return Call number label
- */
+* Extract the call number label from a record
+* @param record
+* @return Call number label
+*/
 public String getCallNumberLabel(Record record) {       
 
-    return getCallNumberLabel(record, "090a:050a");
+return getCallNumberLabel(record, "090a:050a");
 }
 
 /**
- * Extract the call number label from a record
- * @param record
- * @return Call number label
- */
+* Extract the call number label from a record
+* @param record
+* @return Call number label
+*/
 public String getCallNumberLabel(Record record, String fieldSpec) {
-    
-    String val = indexer.getFirstFieldVal(record, fieldSpec);
-    
-    if (val != null) {
-        int dotPos = val.indexOf(".");
-        if (dotPos > 0) {
-            val = val.substring(0, dotPos);
-        }
-        return val.toUpperCase();
-    } else {
-        return val;
-    }
+
+String val = indexer.getFirstFieldVal(record, fieldSpec);
+
+if (val != null) {
+int dotPos = val.indexOf(".");
+if (dotPos > 0) {
+    val = val.substring(0, dotPos);
+}
+return val.toUpperCase();
+} else {
+return val;
+}
 }
 
 /**
- * Extract the subject component of the call number
- *
- * Can return null
- *
- * @param record
- * @return Call number label
- */
+* Extract the subject component of the call number
+*
+* Can return null
+*
+* @param record
+* @return Call number label
+*/
 public String getCallNumberSubject(Record record) {
 
-    return(getCallNumberSubject(record, "090a:050a"));
+return(getCallNumberSubject(record, "090a:050a"));
 }
 
 /**
- * Extract the subject component of the call number
- *
- * Can return null
- *
- * @param record
- * @return Call number label
- */
+* Extract the subject component of the call number
+*
+* Can return null
+*
+* @param record
+* @return Call number label
+*/
 public String getCallNumberSubject(Record record, String fieldSpec) {
 
-    String val = indexer.getFirstFieldVal(record, fieldSpec);
+String val = indexer.getFirstFieldVal(record, fieldSpec);
 
-    if (val != null) {
-        String [] callNumberSubject = val.toUpperCase().split("[^A-Z]+");
-        if (callNumberSubject.length > 0)
-        {
-            return callNumberSubject[0];
-        }
-    }
-    return(null);
+if (val != null) {
+String [] callNumberSubject = val.toUpperCase().split("[^A-Z]+");
+if (callNumberSubject.length > 0)
+{
+    return callNumberSubject[0];
+}
+}
+return(null);
 }
 
 /**
- * Normalize a single LCCN
- * @param record
- * @param fieldSpec
- * @return String Normalized LCCN
- */
+* Normalize a single LCCN
+* @param record
+* @param fieldSpec
+* @return String Normalized LCCN
+*/
 public String getFullCallNumberNormalized(Record record) {
 
-    return(getFullCallNumberNormalized(record, "099ab:090ab:050ab"));
+return(getFullCallNumberNormalized(record, "099ab:090ab:050ab"));
 }
 
 /**
- * Normalize a single LCCN
- * @param record
- * @param fieldSpec
- * @return String Normalized LCCN
- */
+* Normalize a single LCCN
+* @param record
+* @param fieldSpec
+* @return String Normalized LCCN
+*/
 public String getFullCallNumberNormalized(Record record, String fieldSpec) {
 
     if (fieldSpec != null) {
         String cn = indexer.getFirstFieldVal(record, fieldSpec);
-        try {
-            return CallNumUtils.getLCShelfkey(cn, null);
-        } catch(Exception e) {
-            // Don't bail out of indexing just because of a weird call number!
-            //System.out.println("getFullCallNumberNormalized error: " + e);
-        }
+        return (new LCCallNumber(cn)).getShelfKey();
     }
     // If we got this far, we couldn't find a valid value:
     return null;
-}
\ No newline at end of file
+}
diff --git a/import/index_scripts/dewey.bsh b/import/index_scripts/dewey.bsh
index a8ba60c461dccdc9709d8e82b123d4841e0b44fd..46ee633b68ce65290abd04bf5c9a7fad4e334723 100644
--- a/import/index_scripts/dewey.bsh
+++ b/import/index_scripts/dewey.bsh
@@ -34,9 +34,10 @@ public Set getDeweyNumber(Record record, String fieldSpec, String precisionStr)
         // Get the current string to work on:
         String current = iter.next();
 
-        if (CallNumUtils.isValidDewey(current)) {
+        DeweyCallNumber callNum = new DeweyCallNumber(current);
+        if (callNum.isValid()) {
             // Convert the numeric portion of the call number into a float:
-            float currentVal = Float.parseFloat(CallNumUtils.getDeweyB4Cutter(current));
+            float currentVal = Float.parseFloat(callNum.getClassification());
 
             // Round the call number value to the specified precision:
             Float finalVal = new Float(Math.floor(currentVal / precision) * precision);
@@ -74,8 +75,9 @@ public Set getDeweySearchable(Record record, String fieldSpec) {
 
         // Add valid strings to the set, normalizing them to be all uppercase
         // and free from whitespace.
-        if (CallNumUtils.isValidDewey(current)) {
-            result.add(current.toUpperCase().replaceAll(" ", ""));
+        DeweyCallNumber callNum = new DeweyCallNumber(current);
+        if (callNum.isValid()) {
+            result.add(callNum.toString().toUpperCase().replaceAll(" ", ""));
         }
     }
 
@@ -104,8 +106,9 @@ public String getDeweySortable(Record record, String fieldSpec) {
         String current = iter.next();
 
         // If this is a valid Dewey number, return the sortable shelf key:
-        if (CallNumUtils.isValidDewey(current)) {
-            return CallNumUtils.getDeweyShelfKey(current);
+        DeweyCallNumber callNum = new DeweyCallNumber(current);
+        if (callNum.isValid()) {
+            return callNum.getShelfKey();
         }
     }
 
@@ -133,19 +136,13 @@ public List getDeweySortables(Record record, String fieldSpec) {
         // Get the current string to work on:
         String current = iter.next();
 
-        // If this is a valid Dewey number, return the sortable shelf key:
-        if (CallNumUtils.isValidDewey(current)) {
-            result.add(CallNumUtils.getDeweyShelfKey(current));
-        } else {
-            // If the number is invalid, we can't normalize it, but we still want
-            // to put an entry in the sort list so that things don't get out of sync
-            // for the AlphaBrowse indexer -- we'll just use the raw string
-            result.add(current);
-        }
+        // gather all sort keys, even if number is not valid
+        DeweyCallNumber callNum = new DeweyCallNumber(current);
+        result.add(callNum.getShelfKey());
     }
 
     // If we found no call numbers, return null; otherwise, return our results:
     if (result.isEmpty())
         return null;
     return result;
-}
\ No newline at end of file
+}