diff --git a/GenSmsPdu.cabal b/GenSmsPdu.cabal
--- a/GenSmsPdu.cabal
+++ b/GenSmsPdu.cabal
@@ -1,38 +1,152 @@
-Name: GenSmsPdu
-Version: 0.1
-Cabal-Version: >= 1.2
-Build-type: Simple
-License: BSD3
-License-file: LICENSE
-Copyright: Kwanghoon Choi <lazyswamp@gmail.com>
-Author: Kwanghoon Choi <lazyswamp@gmail.com>
-Maintainer: Kwanghoon Choi <lazyswamp@gmail.com>
-Homepage: 
-Category: Testing
-Synopsis: Automatic SMS message generator
-Description: GenSmsPdu is a library for random generation of 3GPP SMS
-            messages. It defines a big data type for 3GPP defined 
-            SMS message formats such as SMS-SUBMIT and SMS-DELIVER \[1\].
-            Using QuickCheck, it can generate a list of random SMS messages
-            in the data type automatically.
-            .
-            GenSmsPdu offers an encoder to convert an SMS message into
-            an SMS PDU (Protocol Data Unit) in bytes, and a decoder to do the reverse. Currently,
-            it generates only single paged SMS messages.
-            .
-            \[1\] 3GPP TS 23.040 V6.7.0, 3rd Generation Partnership Project
-              Technical Specification Group Core Network and Terminals;
-              Technical Realization of the Short Message Service (SMS)
-             (Release 6), March 2006. http:\/\/www.3gpp.org.
-
-Extra-source-files: src/GenSmsPdu.hs
-
-Executable gensmspdu
-  Main-Is: Main.hs
-  hs-source-dirs: src
-  Build-depends: base >= 4 && < 5, random, haskell98, QuickCheck
-  Ghc-options: -fglasgow-exts
-  extensions: MultiParamTypeClasses 
-  extensions: UndecidableInstances
-
-
+cabal-version:      3.0
+-- The cabal-version field refers to the version of the .cabal specification,
+-- and can be different from the cabal-install (the tool) version and the
+-- Cabal (the library) version you are using. As such, the Cabal (the library)
+-- version used must be equal or greater than the version stated in this field.
+-- Starting from the specification version 2.2, the cabal-version field must be
+-- the first thing in the cabal file.
+
+-- Initial package description 'GenSmsPdu' generated by
+-- 'cabal init'. For further documentation, see:
+--   http://haskell.org/cabal/users-guide/
+--
+-- The name of the package.
+name:               GenSmsPdu
+
+-- The package version.
+-- See the Haskell package versioning policy (PVP) for standards
+-- guiding when and how versions should be incremented.
+-- https://pvp.haskell.org
+-- PVP summary:     +-+------- breaking API changes
+--                  | | +----- non-breaking API additions
+--                  | | | +--- code changes with no API change
+version:            0.2.0.0
+
+-- A short (one-line) description of the package.
+-- synopsis:
+
+-- A longer description of the package.
+-- description:
+
+-- URL for the project homepage or repository.
+homepage:           https://github.com/kwanghoon/GenSmsPdu
+
+-- The license under which the package is released.
+license:            BSD-3-Clause
+
+-- The file containing the license text.
+license-file:       LICENSE
+
+-- The package author(s).
+author:             Kwanghoon Choi
+
+-- An email address to which users can send suggestions, bug reports, and patches.
+maintainer:         lazyswamp@gmail.com
+
+-- A copyright notice.
+-- copyright:
+category:           Testing
+build-type:         Simple
+
+-- Synopsis and description:
+Synopsis: Automatic SMS message generator
+Description: GenSmsPdu is a Haskell library designed for the random generation 
+             of 3GPP SMS messages. It includes a comprehensive data type that 
+             encompasses various 3GPP-defined SMS message formats, including 
+             SMS-SUBMIT and SMS-DELIVER. Leveraging QuickCheck, GenSmsPdu is 
+             capable of automatically generating a series of random SMS messages 
+             in this specified data type.
+
+             GenSmsPdu features an encoder that transforms SMS messages into 
+             byte-formatted SMS PDUs (Protocol Data Units), along with a decoder 
+             for the reverse process. At present, it is capable of generating only 
+             single-page SMS messages.
+
+-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README.
+-- extra-doc-files:    CHANGELOG.md
+
+-- Extra source files to be distributed with the package, such as examples, or a tutorial module.
+-- extra-source-files:
+
+common warnings
+    ghc-options: -Wall
+
+library
+    -- Import common warning flags.
+    import:           warnings
+
+    -- Modules exported by the library.
+    exposed-modules:  GenSmsPdu
+
+    -- Modules included in this library but not exported.
+    -- other-modules:
+
+    -- LANGUAGE extensions used by modules in this package.
+    -- other-extensions:
+
+    -- Other library packages from which modules are imported.
+    build-depends:    
+        base ^>=4.17.2.1,
+        random,
+        QuickCheck
+
+    -- Directories containing source files.
+    hs-source-dirs:   src
+
+    -- Base language which the package is written in.
+    default-language: Haskell2010
+
+executable GenSmsPdu
+    -- Import common warning flags.
+    import:           warnings
+
+    -- .hs or .lhs file containing the Main module.
+    main-is:          Main.hs
+
+    -- Modules included in this executable, other than Main.
+    -- other-modules:
+
+    -- LANGUAGE extensions used by modules in this package.
+    -- other-extensions:
+
+    -- Other library packages from which modules are imported.
+    build-depends:
+        base ^>=4.17.2.1,
+        random,
+        QuickCheck,
+        GenSmsPdu
+
+    -- Directories containing source files.
+    hs-source-dirs:   app
+
+    -- Base language which the package is written in.
+    default-language: Haskell2010
+
+test-suite GenSmsPdu-test
+    -- Import common warning flags.
+    import:           warnings
+
+    -- Base language which the package is written in.
+    default-language: Haskell2010
+
+    -- Modules included in this executable, other than Main.
+    -- other-modules:
+
+    -- LANGUAGE extensions used by modules in this package.
+    -- other-extensions:
+
+    -- The interface type and version of the test suite.
+    type:             exitcode-stdio-1.0
+
+    -- Directories containing source files.
+    hs-source-dirs:   test
+
+    -- The entrypoint to the test suite.
+    main-is:          Main.hs
+
+    -- Test dependencies.
+    build-depends:
+        base ^>=4.17.2.1,
+        random,
+        QuickCheck,
+        GenSmsPdu
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,26 +1,30 @@
-Copyright (c) 2010, Kwanghoon Choi
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without 
-modification, are permitted provided that the following conditions are met:
-
-- Redistributions of source code must retain the above copyright notice, 
-  this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright 
-  notice, this list of conditions and the following disclaimer in the 
-  documentation and/or other materials provided with the distribution.
-- Neither the names of the copyright owners nor the names of the 
-  contributors may be used to endorse or promote products derived 
-  from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Copyright (c) 2024, Kwanghoon Choi
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the name of Kwanghoon Choi nor the names of other
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/Setup.lhs b/Setup.lhs
deleted file mode 100644
--- a/Setup.lhs
+++ /dev/null
@@ -1,3 +0,0 @@
-
-> import Distribution.Simple
-> main = defaultMain
diff --git a/app/Main.hs b/app/Main.hs
new file mode 100644
--- /dev/null
+++ b/app/Main.hs
@@ -0,0 +1,12 @@
+module Main where
+
+import System.Environment (getArgs)
+import GenSmsPdu
+
+tr "normal" = Normal
+tr "c"      = GenC
+tr "send"   = Send
+tr _        = Normal
+
+main = do args <- getArgs
+          mapM_ test_suite (map tr (args ++ ["c"]))
diff --git a/src/GenSmsPdu.hs b/src/GenSmsPdu.hs
--- a/src/GenSmsPdu.hs
+++ b/src/GenSmsPdu.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE UndecidableInstances #-}
 
 module GenSmsPdu where
 
@@ -78,13 +81,14 @@
 
 -}
 
-import Char
-import Maybe
+import Data.Char
+import Data.Maybe
 import Control.Monad
 import System.Random
 import System.IO
 import Test.QuickCheck
 import Test.QuickCheck.Gen
+import Test.QuickCheck.Random
 
 class Variant a where
     valid   :: Gen a
@@ -218,7 +222,7 @@
 -- GSM 7bit
 bytesToGsm7bit bytes = 
    let
-      is7bit c = 0 <= Char.ord c && Char.ord c <= 127
+      is7bit c = 0 <= Data.Char.ord c && Data.Char.ord c <= 127
 
       mkOctetList (b0:b1:b2:b3:b4:b5:b6:b7:therest) = b7:b6:b5:b4:b3:b2:b1:b0 : mkOctetList therest
       mkOctetList (b0:b1:b2:b3:b4:b5:b6:[])         = 0:b6:b5:b4:b3:b2:b1:b0 : []
@@ -235,7 +239,7 @@
             reverse $ 
             concat  $ 
             reverse $
-            map (drop 1 . intToBits8 . Char.ord) bytes
+            map (drop 1 . intToBits8 . Data.Char.ord) bytes
    else error ("[bytesToGsm7bit] bytes=" ++ show bytes)
 
 mkOctetList [] = []
@@ -256,14 +260,14 @@
       gsm7bitToBytes' 0   (0:bits) accu = (accu, bits)
       gsm7bitToBytes' 0   bits accu = (accu, bits)
       gsm7bitToBytes' len (b0:b1:b2:b3:b4:b5:b6:bits) accu
-         = gsm7bitToBytes' (len-1) bits (accu ++ [Char.chr (bits8ToInt [0,b6,b5,b4,b3,b2,b1,b0])])
+         = gsm7bitToBytes' (len-1) bits (accu ++ [Data.Char.chr (bits8ToInt [0,b6,b5,b4,b3,b2,b1,b0])])
       gsm7bitToBytes' len bits accu
          = error ("[gsm7bitToBytes gsm7bitToBytes'] accu=" ++ show accu ++ ", len=" ++ show len ++ ", bits=" ++ show bits)
 
 -- 8bit
 bytesToCS8bit bytes =
-   if and (map (\i -> 0<=i && i<=2^8-1) (map Char.ord bytes))
-   then concat $ map (intToBits8 . Char.ord)  bytes
+   if and (map (\i -> 0<=i && i<=2^8-1) (map Data.Char.ord bytes))
+   then concat $ map (intToBits8 . Data.Char.ord)  bytes
    else error ("[bytesToCS8bit] " ++ bytes)
 
 cs8bitToBytes len bits = cs8bitToBytes' len bits
@@ -271,15 +275,15 @@
       cs8bitToBytes' 0 bits = ([], bits)
       cs8bitToBytes' n (b7:b6:b5:b4:b3:b2:b1:b0:bits) 
          = let (bytes', bits') = cs8bitToBytes' (n-1) bits
-           in (Char.chr (bits8ToInt (b7:b6:b5:b4:b3:b2:b1:b0:[]))
+           in (Data.Char.chr (bits8ToInt (b7:b6:b5:b4:b3:b2:b1:b0:[]))
                : bytes', bits')
       cs8bitToBytes' _ _
          = error ("[cs8bitToBytes] len=" ++ show len ++ ", " ++ show bits)
 
 -- UCS2         
 bytesToUCS16bit bytes =
-   if and (map (\i -> 0<=i && i<=2^16-1) (map Char.ord bytes))
-   then concat $ map (intToBits16 . Char.ord) bytes
+   if and (map (\i -> 0<=i && i<=2^16-1) (map Data.Char.ord bytes))
+   then concat $ map (intToBits16 . Data.Char.ord) bytes
    else error ("[bytesToCS16bit] " ++ bytes)
 
 ucs16bitToBytes len bits = ucs16bitToBytes' len bits
@@ -287,7 +291,7 @@
       ucs16bitToBytes' 0 bits = ([], bits)
       ucs16bitToBytes' n (b15:b14:b13:b12:b11:b10:b9:b8:b7:b6:b5:b4:b3:b2:b1:b0:bits) 
          = let (bytes', bits') = ucs16bitToBytes' (n-1) bits
-           in (Char.chr (bits16ToInt (b15:b14:b13:b12:b11:b10:b9:b8:b7:b6:b5:b4:b3:b2:b1:b0:[])) : bytes', bits')
+           in (Data.Char.chr (bits16ToInt (b15:b14:b13:b12:b11:b10:b9:b8:b7:b6:b5:b4:b3:b2:b1:b0:[])) : bytes', bits')
       ucs16bitToBytes' _ _
          = error ("[ucs16bitToBytes] len=" ++ show len ++ ", " ++ show bits)
 
@@ -2317,7 +2321,7 @@
 instance Variant TP_CD where
    valid = do len <- choose (0, 157)
               str <- getRandomText len
-              return (TP_CD (map Char.ord str))
+              return (TP_CD (map Data.Char.ord str))
 
    invalid = valid
 
@@ -2395,7 +2399,7 @@
            concat (map (\(iei,ieidl,ieid)-> intToBits8 iei 
                       ++ intToBits8 ieidl 
                       ++ concat (map intToBits8 ieid)) ieis)
-              ++ concat (map (intToBits8 . Char.ord) short_msg)
+              ++ concat (map (intToBits8 . Data.Char.ord) short_msg)
       | otherwise 
          = error ("[encode] TP_UD " ++ ", " ++ show cs ++ ", " ++ show udl 
                      ++ ", " ++ show udhl ++ ", " ++ show ieis 
@@ -3362,7 +3366,7 @@
 -- | Generates some example values.
 mysample :: Gen a -> IO [a]
 mysample (MkGen m) =
-  do rnd <- newStdGen
+  do rnd <- newQCGen
      let rnds rnd = rnd1 : rnds rnd2 where (rnd1,rnd2) = split rnd
      return [(m r n) | (r,n) <- rnds rnd `zip` [0,2..200] ]
 
diff --git a/src/Main.hs b/src/Main.hs
deleted file mode 100644
--- a/src/Main.hs
+++ /dev/null
@@ -1,13 +0,0 @@
-
-module Main where
-
-import GenSmsPdu
-import System
-
-tr "normal" = Normal
-tr "c" = GenC
-tr "send" = Send
-tr _ = Normal
-
-main = do args <- getArgs
-          mapM_ test_suite (map tr (args ++ ["c"]))
diff --git a/test/Main.hs b/test/Main.hs
new file mode 100644
--- /dev/null
+++ b/test/Main.hs
@@ -0,0 +1,12 @@
+module Main (main) where
+
+import System.Environment (getArgs)
+import GenSmsPdu
+
+tr "normal" = Normal
+tr "c"      = GenC
+tr "send"   = Send
+tr _        = Normal
+
+main = do args <- getArgs
+          mapM_ test_suite (map tr (args ++ ["c"]))
