diff --git a/NEWS b/NEWS
--- a/NEWS
+++ b/NEWS
@@ -1,7 +1,14 @@
 
-Changes in 0.7
---------------
+Changes in 0.7.2:
+* Put all exported unsafe functions in Unsafe.BLAS
 
+Changes in 0.7.1:
+
+* Update minimum Quickcheck version in cabal file
+
+
+Changes in 0.7:
+
 * Get rid of most functional dependencies in favor of type families.
   There is one remaining functional dependency that cannot be gotten
   rid of until GHC implements equality constraints in superclass
@@ -30,8 +37,7 @@
 * Massive code cleanup.
 
 
-Changes in 0.6
---------------
+Changes in 0.6:
 
 * Massive overhaul of the types.  It is now possible to do mutable operations
   in the ST monad.  Access control is done via type classes now instead of
@@ -46,8 +52,7 @@
   now provide access to rows and columns.
   
 
-Changes in 0.5
---------------
+Changes in 0.5:
 
 * Add Banded matrix data type, as well as Tri Banded and Herm Banded.
 
diff --git a/blas.cabal b/blas.cabal
--- a/blas.cabal
+++ b/blas.cabal
@@ -1,5 +1,5 @@
 name:            blas
-version:         0.7.1
+version:         0.7.2
 homepage:        http://github.com/patperry/blas
 synopsis:        Bindings to the BLAS library
 description:
@@ -55,9 +55,7 @@
 
 library
     hs-source-dirs:     lib
-    exposed-modules:    BLAS.Internal
-                        BLAS.CTypes
-
+    exposed-modules:    
                         Data.Elem.BLAS
                         Data.Elem.BLAS.Level1
                         Data.Elem.BLAS.Level2
@@ -69,51 +67,54 @@
 
                         Data.Matrix.Class
                             Data.Matrix.Class.IMatrix
-                            Data.Matrix.Class.IMatrixBase
                             Data.Matrix.Class.MMatrix
-                            Data.Matrix.Class.MMatrixBase
                             Data.Matrix.Class.ISolve
-                            Data.Matrix.Class.ISolveBase
                             Data.Matrix.Class.MSolve
-                            Data.Matrix.Class.MSolveBase
 
                         Data.Matrix.Banded
-                            Data.Matrix.Banded.Base
                             Data.Matrix.Banded.Class
                             Data.Matrix.Banded.IO
-                            Data.Matrix.Banded.IOBase
                             Data.Matrix.Banded.ST
-                            Data.Matrix.Banded.STBase
                         
                         Data.Matrix.Dense
-                            Data.Matrix.Dense.Base
                             Data.Matrix.Dense.Class
                             Data.Matrix.Dense.IO
-                            Data.Matrix.Dense.IOBase
                             Data.Matrix.Dense.ST
-                            Data.Matrix.Dense.STBase
 
                         Data.Matrix.Herm
-                        Data.Matrix.HermBase
                         Data.Matrix.Tri
-                        Data.Matrix.TriBase
 
                         Data.Vector.Dense
-                            Data.Vector.Dense.Base
                             Data.Vector.Dense.Class
                             Data.Vector.Dense.IO
-                            Data.Vector.Dense.IOBase
                             Data.Vector.Dense.ST
-                            Data.Vector.Dense.STBase
 
                         Test.QuickCheck.BLAS
-                        Test.QuickCheck.BLASBase
 
+                        Unsafe.BLAS
+
     other-modules:      
+                        BLAS.Internal
+                        BLAS.CTypes
                         BLAS.Types
                         Data.Elem.BLAS.Base
                         Data.Elem.BLAS.Double
                         Data.Elem.BLAS.Zomplex
+                        Data.Matrix.Class.IMatrixBase
+                        Data.Matrix.Class.MMatrixBase
+                        Data.Matrix.Class.ISolveBase
+                        Data.Matrix.Class.MSolveBase
+                        Data.Matrix.Banded.Base
+                        Data.Matrix.Banded.IOBase
+                        Data.Matrix.Banded.STBase
+                        Data.Matrix.Dense.Base
+                        Data.Matrix.Dense.IOBase
+                        Data.Matrix.Dense.STBase
+                        Data.Matrix.HermBase
+                        Data.Matrix.TriBase
+                        Data.Vector.Dense.Base
+                        Data.Vector.Dense.IOBase
+                        Data.Vector.Dense.STBase
     
     includes:           cbits/config.h
                         cbits/BLAS.h
diff --git a/lib/BLAS/Internal.hs b/lib/BLAS/Internal.hs
--- a/lib/BLAS/Internal.hs
+++ b/lib/BLAS/Internal.hs
@@ -59,7 +59,7 @@
     where
     clearArray' :: Storable e => e -> Ptr e -> Int -> IO ()
     clearArray' e ptr n =
-        let nbytes = (fromInteger . toInteger) (n * sizeOf e)
+        let nbytes = fromIntegral (n * sizeOf e)
         in do
             bzero ptr nbytes
 {-# INLINE clearArray #-}
@@ -68,7 +68,7 @@
 bzero :: Ptr a -> Int -> IO ()
 bzero ptr n =
     let ptr' = castPtr ptr
-        n'   = (fromInteger . toInteger) n
+        n'   = fromIntegral n
     in bzero_ ptr' n'
         
 foreign import ccall "strings.h bzero"
diff --git a/lib/Data/Matrix/Dense/Base.hs b/lib/Data/Matrix/Dense/Base.hs
--- a/lib/Data/Matrix/Dense/Base.hs
+++ b/lib/Data/Matrix/Dense/Base.hs
@@ -416,7 +416,7 @@
 getDiag a = checkedDiag (shape a) (unsafeGetDiag a)
 {-# INLINE getDiag #-}
 
--- | Same as 'getDiag' but not range-checked.
+-- Same as 'getDiag' but not range-checked.
 unsafeGetDiag :: (ReadMatrix a e m, WriteVector y e m) => 
     a (n,p) e -> Int -> m (y k e)
 unsafeGetDiag a i = newCopyVector (unsafeDiagView a i)
@@ -1293,7 +1293,7 @@
     unsafeFreezeIOMatrix =<< newMatrix mn ies
 {-# NOINLINE matrix #-}
 
--- | Same as 'matrix' but does not do any bounds checking.
+-- Same as 'matrix' but does not do any bounds checking.
 unsafeMatrix :: (BLAS3 e) => (Int,Int) -> [((Int,Int), e)] -> Matrix (n,p) e
 unsafeMatrix mn ies =  unsafePerformIO $ 
     unsafeFreezeIOMatrix =<< unsafeNewMatrix mn ies
@@ -1405,7 +1405,7 @@
 diag (Matrix a) i = Vector (diagView a i)
 {-# INLINE diag #-}
 
--- | Same as 'diag' but index is not range-checked.
+-- Same as 'diag' but index is not range-checked.
 unsafeDiag :: (Elem e) => Matrix (n,p) e -> Int -> Vector k e
 unsafeDiag (Matrix a) i = Vector (diagView a i)
 {-# INLINE unsafeDiag #-}
diff --git a/lib/Data/Matrix/Dense/Class.hs b/lib/Data/Matrix/Dense/Class.hs
--- a/lib/Data/Matrix/Dense/Class.hs
+++ b/lib/Data/Matrix/Dense/Class.hs
@@ -62,6 +62,8 @@
     diagView,
 
     -- * Conversions between matrices and vectors
+    liftMatrix,
+    liftMatrix2,
     maybeViewMatrixAsVector,
     maybeViewVectorAsMatrix,
     maybeViewVectorAsRow,
diff --git a/lib/Data/Vector/Dense/Base.hs b/lib/Data/Vector/Dense/Base.hs
--- a/lib/Data/Vector/Dense/Base.hs
+++ b/lib/Data/Vector/Dense/Base.hs
@@ -259,7 +259,7 @@
 swapVector x y = checkBinaryOp (shape x) (shape y) $ unsafeSwapVector x y
 {-# INLINE swapVector #-}
 
-unsafeSwapVector :: (ReadVector x e m, ReadVector y e m) =>
+unsafeSwapVector :: (WriteVector x e m, WriteVector y e m) =>
     x n e -> y n e -> m ()
 unsafeSwapVector x y
     | isConj x =
@@ -545,7 +545,7 @@
     unsafeFreezeIOVector =<< newVector n ies
 {-# NOINLINE vector #-}
 
--- | Same as 'vector', but does not range-check the indices.
+-- Same as 'vector', but does not range-check the indices.
 unsafeVector :: (BLAS1 e) => Int -> [(Int, e)] -> Vector n e
 unsafeVector n ies = unsafePerformIO $
     unsafeFreezeIOVector =<< unsafeNewVector n ies
@@ -606,6 +606,11 @@
 unsafeSubvector = unsafeSubvectorView
 {-# INLINE unsafeSubvector #-}
 
+unsafeSubvectorWithStride :: (Elem e) =>
+    Int -> Vector n e -> Int -> Int -> Vector n' e
+unsafeSubvectorWithStride = unsafeSubvectorViewWithStride
+{-# INLINE unsafeSubvectorWithStride #-}
+
 -- | @subvectorWithStride s x o n@ creates a subvector of @x@ starting 
 -- at index @o@, having length @n@ and stride @s@.
 subvectorWithStride :: (BLAS1 e) =>
@@ -697,6 +702,10 @@
 (<.>) :: (BLAS1 e) => Vector n e -> Vector n e -> e
 (<.>) x y = unsafePerformIO $ getDot x y
 {-# NOINLINE (<.>) #-}
+
+unsafeDot :: (BLAS1 e) => Vector n e -> Vector n e -> e
+unsafeDot x y = unsafePerformIO $ unsafeGetDot x y
+{-# NOINLINE unsafeDot #-}
 
 instance Shaped Vector Int where
     shape (Vector x) = shapeIOVector x
diff --git a/lib/Test/QuickCheck/BLAS.hs b/lib/Test/QuickCheck/BLAS.hs
--- a/lib/Test/QuickCheck/BLAS.hs
+++ b/lib/Test/QuickCheck/BLAS.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# OPTIONS_GHC -fno-warn-orphans #-}
 -----------------------------------------------------------------------------
 -- |
 -- Module     : Test.QuickCheck.BLAS
@@ -6,6 +8,7 @@
 -- Maintainer : Patrick Perry <patperry@stanford.edu>
 -- Stability  : experimental
 --
+--
 -- Test generators for BLAS types.
 --
 
@@ -31,4 +34,181 @@
     banded,
     ) where
 
-import Test.QuickCheck.BLASBase
+import Control.Monad
+import Data.Maybe( fromJust )
+
+import Test.QuickCheck hiding ( vector, elements )
+import qualified Test.QuickCheck as QC
+
+import Data.Vector.Dense( Vector, listVector, subvectorWithStride,
+    conj )
+import Data.Matrix.Dense( Matrix, listMatrix, herm, submatrix )
+import Data.Matrix.Banded( Banded, maybeBandedFromMatrixStorage )
+import Data.Elem.BLAS
+
+-- | Element types that can be tested with QuickCheck properties.
+class (BLAS3 e, Arbitrary e) => TestElem e where
+    -- | Inicates whether or not the value should be used in tests.  For
+    -- 'Double's, @isTestElemElem e@ is defined as 
+    -- @not (isNaN e || isInfinite e || isDenormalized e)@.
+    isTestElemElem :: e -> Bool
+    
+instance TestElem Double where
+    isTestElemElem e = not (isNaN e || isInfinite e || isDenormalized e)
+    {-# INLINE isTestElemElem #-}
+
+instance Arbitrary (Complex Double) where
+    arbitrary = liftM2 (:+) arbitrary arbitrary
+    {-# INLINE arbitrary #-}
+    coarbitrary (x:+y) = coarbitrary (x,y)
+    {-# INLINE coarbitrary #-}
+
+instance TestElem (Complex Double) where
+    isTestElemElem (x :+ y) = isTestElemElem x && isTestElemElem y
+    {-# INLINE isTestElemElem #-}
+    
+-- | Generate a list of elements suitable for testing with.
+elements :: (TestElem e) => Int -> Gen [e]
+elements n = do
+    es <- liftM (filter isTestElemElem) $ QC.vector n
+    let n' = length es
+    if n' < n
+        then liftM (es ++) $ elements (n-n')
+        else return es
+
+-- | Generate a list of elements for testing that have no imaginary part.
+realElements :: (TestElem e) => Int -> Gen [e]
+realElements n = liftM (map fromReal) $ elements n
+
+-- | Get an appropriate dimension for a random vector
+dim :: Gen Int
+dim = liftM abs arbitrary
+
+-- | Generate a random vector of the given size.
+vector :: (TestElem e) => Int -> Gen (Vector n e)
+vector n =
+    frequency [ (3, rawVector n)  
+              , (2, conjVector n)
+              , (1, subVector n    >>= \(SubVector s x o _) -> 
+                    return $ subvectorWithStride s x o n)
+              ]    
+
+data SubVector n e = 
+    SubVector Int 
+              (Vector n e) 
+              Int 
+              Int 
+    deriving (Show)
+
+instance (TestElem e) => Arbitrary (SubVector n e) where
+    arbitrary = sized $ \m -> 
+        choose (0,m) >>= subVector
+        
+    coarbitrary = undefined
+
+rawVector :: (TestElem e) => Int -> Gen (Vector n e)
+rawVector n = do
+    es <- elements n
+    return $ listVector n es
+
+conjVector :: (TestElem e) => Int -> Gen (Vector n e)
+conjVector n = do
+    x <- vector n
+    return $ (conj x)
+
+subVector :: (TestElem e) => Int -> Gen (SubVector n e)
+subVector n = do
+    o <- choose (0,5)
+    s <- choose (1,5)
+    e <- choose (0,5)
+    x <- vector (o + s*n + e)
+    return (SubVector s x o n)
+
+data SubMatrix m n e = 
+    SubMatrix (Matrix (m,n) e) 
+              (Int,Int) 
+              (Int,Int) 
+    deriving (Show)
+
+-- | Generate an appropriate shape for a random matrix.
+shape :: Gen (Int,Int)
+shape = sized $ \s ->
+    let s' = (ceiling . sqrt) (fromIntegral s :: Double)
+    in liftM2 (,) (choose (0,s')) (choose (0,1+s'))
+
+-- | Generate a random matrix of the given shape.
+matrix :: (TestElem e) => (Int,Int) -> Gen (Matrix (m,n) e)
+matrix mn = frequency [ (3, rawMatrix mn)  
+                      , (2, hermedMatrix mn)
+                      , (1, subMatrix mn >>= \(SubMatrix a ij _) -> 
+                                 return $ submatrix a ij mn)
+                      ]
+
+rawMatrix :: (TestElem e) => (Int,Int) -> Gen (Matrix (m,n) e)
+rawMatrix (m,n) = do
+    es <- elements (m*n)
+    return $ listMatrix (m,n) es
+
+hermedMatrix :: (TestElem e) => (Int,Int) -> Gen (Matrix (m,n) e)
+hermedMatrix (m,n) = do
+    x <- matrix (n,m)
+    return $ (herm x)
+
+subMatrix :: (TestElem e) => (Int,Int) -> Gen (SubMatrix m n e)
+subMatrix (m,n) = 
+    oneof [ rawSubMatrix (m,n)
+          , rawSubMatrix (n,m) >>= \(SubMatrix a (i,j) (m',n')) ->
+                return $ SubMatrix (herm a) (j,i) (n',m')
+          ]
+
+rawSubMatrix :: (TestElem e) => (Int,Int) -> Gen (SubMatrix m n e)
+rawSubMatrix (m,n) = do
+    i <- choose (0,5)
+    j <- choose (0,5)
+    e <- choose (0,5)
+    f <- choose (0,5)
+    x <- rawMatrix (i+m+e, j+n+f)
+    return $ SubMatrix x (i,j) (m,n)
+
+instance (TestElem e) => Arbitrary (SubMatrix m n e) where
+    arbitrary = do
+        (m,n) <- shape
+        (SubMatrix a ij mn) <- subMatrix (m,n)
+        return $ SubMatrix a ij mn
+        
+    coarbitrary = undefined
+
+-- | Generate valid bandwidth for a given matrix dimension size
+bandwidth :: Int -> Gen Int
+bandwidth n = if n == 0 then return 0 else choose (0,n-1)
+    
+-- | Generate valid bandwidths for the given matrix shape.
+bandwidths :: (Int,Int) -> Gen (Int,Int)
+bandwidths (m,n) = liftM2 (,) (bandwidth m) (bandwidth n)
+
+-- | Generate a random banded matrix.
+banded :: (TestElem e) => 
+    (Int,Int) -> (Int,Int) -> Gen (Banded (m,n) e)
+banded mn lu = frequency [ (3, rawBanded mn lu)  
+                         , (2, hermedBanded mn lu)
+                         ]
+
+rawBanded :: (TestElem e) => 
+    (Int,Int) -> (Int,Int) -> Gen (Banded (m,n) e)
+rawBanded (m,n) (kl,ku) = 
+    let bw = kl+ku+1
+    in do
+        a <- frequency [ (2, rawMatrix (bw,n))
+                       , (1, rawSubMatrix (bw,n) >>= \(SubMatrix b ij _) ->
+                                 return $ submatrix b ij (bw,n))     
+                       ]
+        return $ fromJust (maybeBandedFromMatrixStorage (m,n) (kl,ku) a)
+
+hermedBanded :: (TestElem e) => 
+    (Int,Int) -> (Int,Int) -> Gen (Banded (m,n) e)
+hermedBanded (m,n) (kl,ku) = do
+    x <- rawBanded (n,m) (ku,kl)
+    return $ herm x
+
+
+
diff --git a/lib/Test/QuickCheck/BLASBase.hs b/lib/Test/QuickCheck/BLASBase.hs
deleted file mode 100644
--- a/lib/Test/QuickCheck/BLASBase.hs
+++ /dev/null
@@ -1,193 +0,0 @@
-{-# LANGUAGE FlexibleInstances #-}
-{-# OPTIONS_HADDOCK hide #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
------------------------------------------------------------------------------
--- |
--- Module     : Test.QuickCheck.BLASBase
--- Copyright  : Copyright (c) , Patrick Perry <patperry@stanford.edu>
--- License    : BSD3
--- Maintainer : Patrick Perry <patperry@stanford.edu>
--- Stability  : experimental
---
-
-module Test.QuickCheck.BLASBase
-    where
-        
-import Control.Monad
-import Data.Maybe( fromJust )
-
-import Test.QuickCheck hiding ( vector, elements )
-import qualified Test.QuickCheck as QC
-
-import Data.Vector.Dense( Vector, listVector, subvectorWithStride,
-    conj )
-import Data.Matrix.Dense( Matrix, listMatrix, herm, submatrix )
-import Data.Matrix.Banded( Banded, maybeBandedFromMatrixStorage )
-import Data.Elem.BLAS
-
--- | Element types that can be tested with QuickCheck properties.
-class (BLAS3 e, Arbitrary e) => TestElem e where
-    -- | Inicates whether or not the value should be used in tests.  For
-    -- 'Double's, @isTestElemElem e@ is defined as 
-    -- @not (isNaN e || isInfinite e || isDenormalized e)@.
-    isTestElemElem :: e -> Bool
-    
-instance TestElem Double where
-    isTestElemElem e = not (isNaN e || isInfinite e || isDenormalized e)
-    {-# INLINE isTestElemElem #-}
-
-instance Arbitrary (Complex Double) where
-    arbitrary = liftM2 (:+) arbitrary arbitrary
-    {-# INLINE arbitrary #-}
-    coarbitrary (x:+y) = coarbitrary (x,y)
-    {-# INLINE coarbitrary #-}
-
-instance TestElem (Complex Double) where
-    isTestElemElem (x :+ y) = isTestElemElem x && isTestElemElem y
-    {-# INLINE isTestElemElem #-}
-    
--- | Generate a list of elements suitable for testing with.
-elements :: (TestElem e) => Int -> Gen [e]
-elements n = do
-    es <- liftM (filter isTestElemElem) $ QC.vector n
-    let n' = length es
-    if n' < n
-        then liftM (es ++) $ elements (n-n')
-        else return es
-
--- | Generate a list of elements for testing that have no imaginary part.
-realElements :: (TestElem e) => Int -> Gen [e]
-realElements n = liftM (map fromReal) $ elements n
-
--- | Get an appropriate dimension for a random vector
-dim :: Gen Int
-dim = liftM abs arbitrary
-
--- | Generate a random vector of the given size.
-vector :: (TestElem e) => Int -> Gen (Vector n e)
-vector n =
-    frequency [ (3, rawVector n)  
-              , (2, conjVector n)
-              , (1, subVector n    >>= \(SubVector s x o _) -> 
-                    return $ subvectorWithStride s x o n)
-              ]    
-
-data SubVector n e = 
-    SubVector Int 
-              (Vector n e) 
-              Int 
-              Int 
-    deriving (Show)
-
-instance (TestElem e) => Arbitrary (SubVector n e) where
-    arbitrary = sized $ \m -> 
-        choose (0,m) >>= subVector
-        
-    coarbitrary = undefined
-
-rawVector :: (TestElem e) => Int -> Gen (Vector n e)
-rawVector n = do
-    es <- elements n
-    return $ listVector n es
-
-conjVector :: (TestElem e) => Int -> Gen (Vector n e)
-conjVector n = do
-    x <- vector n
-    return $ (conj x)
-
-subVector :: (TestElem e) => Int -> Gen (SubVector n e)
-subVector n = do
-    o <- choose (0,5)
-    s <- choose (1,5)
-    e <- choose (0,5)
-    x <- vector (o + s*n + e)
-    return (SubVector s x o n)
-
-data SubMatrix m n e = 
-    SubMatrix (Matrix (m,n) e) 
-              (Int,Int) 
-              (Int,Int) 
-    deriving (Show)
-
--- | Generate an appropriate shape for a random matrix.
-shape :: Gen (Int,Int)
-shape = sized $ \s ->
-    let s' = (ceiling . sqrt) (fromIntegral s :: Double)
-    in liftM2 (,) (choose (0,s')) (choose (0,1+s'))
-
--- | Generate a random matrix of the given shape.
-matrix :: (TestElem e) => (Int,Int) -> Gen (Matrix (m,n) e)
-matrix mn = frequency [ (3, rawMatrix mn)  
-                      , (2, hermedMatrix mn)
-                      , (1, subMatrix mn >>= \(SubMatrix a ij _) -> 
-                                 return $ submatrix a ij mn)
-                      ]
-
-rawMatrix :: (TestElem e) => (Int,Int) -> Gen (Matrix (m,n) e)
-rawMatrix (m,n) = do
-    es <- elements (m*n)
-    return $ listMatrix (m,n) es
-
-hermedMatrix :: (TestElem e) => (Int,Int) -> Gen (Matrix (m,n) e)
-hermedMatrix (m,n) = do
-    x <- matrix (n,m)
-    return $ (herm x)
-
-subMatrix :: (TestElem e) => (Int,Int) -> Gen (SubMatrix m n e)
-subMatrix (m,n) = 
-    oneof [ rawSubMatrix (m,n)
-          , rawSubMatrix (n,m) >>= \(SubMatrix a (i,j) (m',n')) ->
-                return $ SubMatrix (herm a) (j,i) (n',m')
-          ]
-
-rawSubMatrix :: (TestElem e) => (Int,Int) -> Gen (SubMatrix m n e)
-rawSubMatrix (m,n) = do
-    i <- choose (0,5)
-    j <- choose (0,5)
-    e <- choose (0,5)
-    f <- choose (0,5)
-    x <- rawMatrix (i+m+e, j+n+f)
-    return $ SubMatrix x (i,j) (m,n)
-
-instance (TestElem e) => Arbitrary (SubMatrix m n e) where
-    arbitrary = do
-        (m,n) <- shape
-        (SubMatrix a ij mn) <- subMatrix (m,n)
-        return $ SubMatrix a ij mn
-        
-    coarbitrary = undefined
-
--- | Generate valid bandwidth for a given matrix dimension size
-bandwidth :: Int -> Gen Int
-bandwidth n = if n == 0 then return 0 else choose (0,n-1)
-    
--- | Generate valid bandwidths for the given matrix shape.
-bandwidths :: (Int,Int) -> Gen (Int,Int)
-bandwidths (m,n) = liftM2 (,) (bandwidth m) (bandwidth n)
-
--- | Generate a random banded matrix.
-banded :: (TestElem e) => 
-    (Int,Int) -> (Int,Int) -> Gen (Banded (m,n) e)
-banded mn lu = frequency [ (3, rawBanded mn lu)  
-                         , (2, hermedBanded mn lu)
-                         ]
-
-rawBanded :: (TestElem e) => 
-    (Int,Int) -> (Int,Int) -> Gen (Banded (m,n) e)
-rawBanded (m,n) (kl,ku) = 
-    let bw = kl+ku+1
-    in do
-        a <- frequency [ (2, rawMatrix (bw,n))
-                       , (1, rawSubMatrix (bw,n) >>= \(SubMatrix b ij _) ->
-                                 return $ submatrix b ij (bw,n))     
-                       ]
-        return $ fromJust (maybeBandedFromMatrixStorage (m,n) (kl,ku) a)
-
-hermedBanded :: (TestElem e) => 
-    (Int,Int) -> (Int,Int) -> Gen (Banded (m,n) e)
-hermedBanded (m,n) (kl,ku) = do
-    x <- rawBanded (n,m) (ku,kl)
-    return $ herm x
-
-
-
diff --git a/lib/Unsafe/BLAS.hs b/lib/Unsafe/BLAS.hs
new file mode 100644
--- /dev/null
+++ b/lib/Unsafe/BLAS.hs
@@ -0,0 +1,114 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module     : Unsafe.BLAS
+-- Copyright  : Copyright (c) , Patrick Perry <patperry@stanford.edu>
+-- License    : BSD3
+-- Maintainer : Patrick Perry <patperry@stanford.edu>
+-- Stability  : experimental
+--
+-- Unsafe BLAS functions.  Most of these functions to not check the
+-- shapes of their arguments, and should be used with caution.
+--
+
+module Unsafe.BLAS (
+
+    -- * Utility functions
+    clearArray,
+    inlinePerformIO,
+
+    -- * Vector functions
+    IOVector(..),
+    unsafeIOVectorToVector,
+    unsafeVector,
+    unsafeSubvector,
+    unsafeSubvectorWithStride,
+    unsafeDot,
+    
+    unsafeNewVector,
+    unsafeCopyVector,
+    unsafeSwapVector,
+    unsafeSubvectorView,
+    unsafeSubvectorViewWithStride,
+    unsafeGetAddVector,
+    unsafeGetSubVector,
+    unsafeGetMulVector,
+    unsafeGetDivVector,
+    unsafeAxpyVector,
+    unsafeAddVector,
+    unsafeSubVector,
+    unsafeMulVector,
+    unsafeDivVector,
+    unsafeGetDot,
+
+    -- * Matrix functions
+    IOMatrix(..),
+    unsafeIOMatrixToMatrix,
+    
+    unsafeSubmatrixView,
+    unsafeDiagView,
+    unsafeRowView,
+    unsafeColView,
+
+    unsafeMatrix,
+    unsafeSubmatrix,
+    unsafeDiag,
+    
+    unsafeNewMatrix,
+    unsafeCopyMatrix,
+    unsafeSwapMatrix,
+    unsafeSwapRows,
+    unsafeSwapCols,
+    unsafeGetDiag,
+    unsafeGetAddMatrix,
+    unsafeGetSubMatrix,
+    unsafeGetMulMatrix,
+    unsafeGetDivMatrix,
+    unsafeAxpyMatrix,
+    unsafeAddMatrix,
+    unsafeSubMatrix,
+    unsafeMulMatrix,
+    unsafeDivMatrix,
+    
+    -- * Banded functions
+    IOBanded(..),
+    unsafeIOBandedToBanded,
+    
+    unsafeDiagViewBanded,
+    unsafeRowViewBanded,
+    unsafeColViewBanded,
+    
+    unsafeBanded,
+    
+    unsafeNewBanded,
+    unsafeGetDiagBanded,
+    unsafeGetRowBanded,
+    unsafeGetColBanded,
+    
+    unsafeDiagBanded,
+    
+    -- * Matrix type classes
+    IMatrix( ),
+    ISolve( ),
+    MMatrix(..),
+    getRowsIO,
+    getRowsST,
+    getColsIO,
+    getColsST,
+    MSolve(..),
+
+    ) where
+
+import BLAS.Internal
+
+import Data.Vector.Dense.Base
+import Data.Vector.Dense.IOBase
+import Data.Matrix.Dense.Base
+import Data.Matrix.Dense.IOBase
+import Data.Matrix.Banded.Base
+import Data.Matrix.Banded.IOBase
+
+import Data.Matrix.Class.ISolveBase
+import Data.Matrix.Class.IMatrixBase
+import Data.Matrix.Class.MMatrixBase
+import Data.Matrix.Class.MSolveBase
+
diff --git a/tests/Banded.hs b/tests/Banded.hs
--- a/tests/Banded.hs
+++ b/tests/Banded.hs
@@ -15,10 +15,26 @@
 import Data.Vector.Dense 
 import Data.Matrix.Dense ( Matrix, identityMatrix )
 import Data.Matrix.Banded
-import Data.Matrix.Banded.Base( listsFromBanded )
 
 import Test.Matrix.Banded hiding ( banded )
         
+
+listsFromBanded :: (BLAS1 e) => Banded np e -> ((Int,Int), (Int,Int),[[e]])
+listsFromBanded a = ( (m,n)
+            , (kl,ku)
+            , map paddedDiag [(-kl)..ku]
+            )
+  where
+    (m,n)   = shape a
+    (kl,ku) = bandwidths (coerceBanded a)
+    
+    padBegin i   = replicate (max (-i) 0)    0
+    padEnd   i   = replicate (max (m-n+i) 0) 0
+    paddedDiag i = (  padBegin i
+                   ++ elems (diagBanded (coerceBanded a) i) 
+                   ++ padEnd i 
+                   )
+                   
 type V = Vector Int E
 type M = Matrix (Int,Int) E
 type B = Banded (Int,Int) E
diff --git a/tests/Test/Matrix/Dense.hs b/tests/Test/Matrix/Dense.hs
--- a/tests/Test/Matrix/Dense.hs
+++ b/tests/Test/Matrix/Dense.hs
@@ -24,7 +24,6 @@
 
 import Test.QuickCheck hiding ( Test.vector )
 import Test.QuickCheck.BLAS ( TestElem )
-import Test.QuickCheck.BLASBase( SubMatrix(..) )
 import qualified Test.QuickCheck.BLAS as Test
 
 import Data.Vector.Dense ( Vector, dim )
@@ -38,6 +37,25 @@
 instance (TestElem e) => Arbitrary (Matrix (m,n) e) where
     arbitrary   = Test.matrix =<< Test.shape
     coarbitrary = undefined
+
+data SubMatrix m n e = 
+    SubMatrix (Matrix (m,n) e) 
+              (Int,Int) 
+              (Int,Int) 
+    deriving (Show)
+
+instance (TestElem e) => Arbitrary (SubMatrix m n e) where
+    arbitrary = do
+        (m,n) <- Test.shape
+        i <- choose (0,5)
+        j <- choose (0,5)
+        e <- choose (0,5)
+        f <- choose (0,5)
+        a <- Test.matrix (i+m+e, j+n+f)
+        return $ SubMatrix a (i,j) (m,n)
+        
+    coarbitrary = undefined
+
 
 data MatrixAt m n e =
     MatrixAt (Matrix (m,n) e)
diff --git a/tests/Test/Matrix/Herm/Banded.hs b/tests/Test/Matrix/Herm/Banded.hs
--- a/tests/Test/Matrix/Herm/Banded.hs
+++ b/tests/Test/Matrix/Herm/Banded.hs
@@ -20,13 +20,29 @@
 import Test.QuickCheck.BLAS ( TestElem )
 import qualified Test.QuickCheck.BLAS as Test
 
-import Data.Elem.BLAS ( Elem, BLAS3, fromReal, conjugate )
+import Data.Elem.BLAS ( Elem, BLAS1, BLAS3, fromReal, conjugate )
 
 import Data.Vector.Dense ( Vector )
 import Data.Matrix.Banded
-import Data.Matrix.Banded.Base( listsFromBanded )
 import Data.Matrix.Dense ( Matrix )
 import Data.Matrix.Herm
+
+listsFromBanded :: (BLAS1 e) => Banded np e -> ((Int,Int), (Int,Int),[[e]])
+listsFromBanded a = ( (m,n)
+            , (kl,ku)
+            , map paddedDiag [(-kl)..ku]
+            )
+  where
+    (m,n)   = shape a
+    (kl,ku) = bandwidths (coerceBanded a)
+    
+    padBegin i   = replicate (max (-i) 0)    0
+    padEnd   i   = replicate (max (m-n+i) 0) 0
+    paddedDiag i = (  padBegin i
+                   ++ elems (diagBanded (coerceBanded a) i) 
+                   ++ padEnd i 
+                   )
+                   
 
 
 
diff --git a/tests/Test/Matrix/Tri/Banded.hs b/tests/Test/Matrix/Tri/Banded.hs
--- a/tests/Test/Matrix/Tri/Banded.hs
+++ b/tests/Test/Matrix/Tri/Banded.hs
@@ -27,14 +27,29 @@
 import Data.Vector.Dense ( Vector )
 import Data.Matrix.Dense ( Matrix )
 import Data.Matrix.Banded
-import Data.Matrix.Banded.Base( listsFromBanded )
-import Data.Elem.BLAS ( BLAS3 )
+import Data.Elem.BLAS ( BLAS1, BLAS3 )
 
 import Data.Matrix.Tri ( Tri, triFromBase )
 import Data.Matrix.Class( UpLoEnum(..), DiagEnum(..) )
 
 import Unsafe.Coerce
 
+listsFromBanded :: (BLAS1 e) => Banded np e -> ((Int,Int), (Int,Int),[[e]])
+listsFromBanded a = ( (m,n)
+            , (kl,ku)
+            , map paddedDiag [(-kl)..ku]
+            )
+  where
+    (m,n)   = shape a
+    (kl,ku) = bandwidths (coerceBanded a)
+    
+    padBegin i   = replicate (max (-i) 0)    0
+    padEnd   i   = replicate (max (m-n+i) 0) 0
+    paddedDiag i = (  padBegin i
+                   ++ elems (diagBanded (coerceBanded a) i) 
+                   ++ padEnd i 
+                   )
+                   
 triBanded :: (TestElem e) => UpLoEnum -> DiagEnum -> Int -> Int -> Gen (Banded (n,n) e)
 triBanded Upper NonUnit n k = do
     a <- triBanded Upper Unit n k
diff --git a/tests/Test/Vector/Dense.hs b/tests/Test/Vector/Dense.hs
--- a/tests/Test/Vector/Dense.hs
+++ b/tests/Test/Vector/Dense.hs
@@ -19,7 +19,6 @@
 
 import Test.QuickCheck hiding ( vector )
 import Test.QuickCheck.BLAS ( TestElem )
-import Test.QuickCheck.BLASBase( SubVector(..) )
 import qualified Test.QuickCheck.BLAS as Test
 
 import Data.Vector.Dense hiding ( vector )
@@ -40,14 +39,15 @@
     deriving (Show)
 
 instance (TestElem e) => Arbitrary (Vector n e) where
-    arbitrary = sized $ \m ->
-        choose (0,m) >>= vector
+    arbitrary = do
+        n <- Test.dim
+        Test.vector n
         
     coarbitrary = undefined
 
 instance (TestElem e) => Arbitrary (VectorPair n e) where
-    arbitrary = sized $ \m -> do
-        n <- choose (0,m)
+    arbitrary = do
+        n <- Test.dim
         x <- vector n
         y <- vector n
         return $ VectorPair x y
@@ -55,11 +55,29 @@
     coarbitrary = undefined
         
 instance (TestElem e) => Arbitrary (VectorTriple n e) where
-    arbitrary = sized $ \m -> do
-        n <- choose (0,m)
+    arbitrary = do
+        n <- Test.dim
         x <- vector n
         y <- vector n
         z <- vector n
         return $ VectorTriple x y z
     
+    coarbitrary = undefined
+
+data SubVector n e = 
+    SubVector Int 
+              (Vector n e) 
+              Int 
+              Int 
+    deriving (Show)
+
+instance (TestElem e) => Arbitrary (SubVector n e) where
+    arbitrary = do
+        n <- Test.dim
+        o <- choose (0,5)
+        s <- choose (1,5)
+        e <- choose (0,5)
+        x <- Test.vector (o + s*n + e)
+        return (SubVector s x o n)
+        
     coarbitrary = undefined
