diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+Version 4.3.2
+-----
+
+* Added functions splitStreamFiltering, splitStreamFilteringQueueing to filter when 
+  splitting the input stream.
+
+* Explicit exporting function newRandomGenerator01 for generating random numbers by 
+  the specified custom generator returning numbers from 0 to 1.
+  
+* Added function freezeList for the double linked list.
+
+* Added an immutable priority queue.
+
 Version 4.3.1
 -----
 
diff --git a/Simulation/Aivika/DoubleLinkedList.hs b/Simulation/Aivika/DoubleLinkedList.hs
--- a/Simulation/Aivika/DoubleLinkedList.hs
+++ b/Simulation/Aivika/DoubleLinkedList.hs
@@ -23,7 +23,8 @@
         listContains,
         listContainsBy,
         listFirst,
-        listLast) where 
+        listLast,
+        freezeList) where 
 
 import Data.IORef
 import Data.Maybe
@@ -225,3 +226,10 @@
                  if not f
                    then readIORef (itemNext item) >>= loop
                    else return $ Just (itemVal item)
+
+-- | Freeze the list and return its contents.
+freezeList :: DoubleLinkedList a -> IO [a]
+freezeList x = readIORef (listTail x) >>= loop []
+  where loop acc Nothing     = return acc
+        loop acc (Just item) = readIORef (itemPrev item) >>= loop (itemVal item : acc)
+  
diff --git a/Simulation/Aivika/Generator.hs b/Simulation/Aivika/Generator.hs
--- a/Simulation/Aivika/Generator.hs
+++ b/Simulation/Aivika/Generator.hs
@@ -16,7 +16,8 @@
         GeneratorType(..),
         DiscretePDF(..),
         newGenerator,
-        newRandomGenerator) where
+        newRandomGenerator,
+        newRandomGenerator01) where
 
 import System.Random
 import Data.IORef
diff --git a/Simulation/Aivika/PriorityQueue/Pure.hs b/Simulation/Aivika/PriorityQueue/Pure.hs
new file mode 100644
--- /dev/null
+++ b/Simulation/Aivika/PriorityQueue/Pure.hs
@@ -0,0 +1,76 @@
+
+-- |
+-- Module     : Simulation.Aivika.PriorityQueue.Pure
+-- Copyright  : Copyright (c) 2015-2016, David Sorokin <david.sorokin@gmail.com>
+-- License    : BSD3
+-- Maintainer : David Sorokin <david.sorokin@gmail.com>
+-- Stability  : experimental
+-- Tested with: GHC 7.10.3
+--
+-- An immutable heap-based priority queue based on book
+-- Algorithms: A Functional Programming Approach by
+-- Fethi Rabhi and Guy Lapalme.
+--
+module Simulation.Aivika.PriorityQueue.Pure 
+       (PriorityQueue, 
+        queueNull, 
+        queueCount,
+        emptyQueue, 
+        enqueue, 
+        dequeue, 
+        queueFront) where 
+
+import Control.Monad
+
+-- | The 'PriorityQueue' type represents an immutable heap-based priority queue.
+data PriorityQueue a = EmptyQueue
+                     | Queue !Int !Double a !Int (PriorityQueue a) (PriorityQueue a)
+                       deriving Show
+
+-- | Test whether the priority queue is empty.
+queueNull :: PriorityQueue a -> Bool
+queueNull EmptyQueue = True
+queueNull _          = False
+
+-- | Return the number of elements in the priority queue.
+queueCount :: PriorityQueue a -> Int
+queueCount EmptyQueue = 0
+queueCount (Queue n k v r a b) = n
+
+-- | An empty priority queue.
+emptyQueue :: PriorityQueue a
+emptyQueue = EmptyQueue
+
+-- | Enqueue a new element with the specified priority.
+enqueue :: PriorityQueue a -> Double -> a -> PriorityQueue a
+enqueue pq k v = mergeQueues (Queue 1 k v 1 EmptyQueue EmptyQueue) pq
+
+-- | Dequeue the element with the minimal priority.
+dequeue :: PriorityQueue a -> PriorityQueue a
+dequeue EmptyQueue = error "The queue is empty: dequeue"
+dequeue (Queue n k v r a b) = mergeQueues a b
+
+-- | Return the element with the minimal priority.
+queueFront :: PriorityQueue a -> (Double, a)
+queueFront EmptyQueue = error "The queue is empty: queueFront"
+queueFront (Queue n k v r a b) = (k, v)
+
+-- | Return the rank of the priority queue.
+queueRank :: PriorityQueue a -> Int
+queueRank EmptyQueue = 0
+queueRank (Queue n k v r a b) = r
+
+-- | Construct a new priority queue.
+makeQueue :: Double -> a -> PriorityQueue a -> PriorityQueue a -> PriorityQueue a
+makeQueue k v a b
+  | queueRank a >= queueRank b = n `seq` Queue n k v (queueRank b + 1) a b
+  | otherwise                  = n `seq` Queue n k v (queueRank a + 1) b a
+  where n = queueCount a + queueCount b + 1
+
+-- | Merge two priority queues.
+mergeQueues :: PriorityQueue a -> PriorityQueue a -> PriorityQueue a
+mergeQueues h EmptyQueue = h
+mergeQueues EmptyQueue h = h
+mergeQueues h1@(Queue _ k1 v1 _ a1 b1) h2@(Queue _ k2 v2 _ a2 b2)
+  | k1 <= k2  = makeQueue k1 v1 a1 (mergeQueues b1 h2)
+  | otherwise = makeQueue k2 v2 a2 (mergeQueues h1 b2)
diff --git a/Simulation/Aivika/Stream.hs b/Simulation/Aivika/Stream.hs
--- a/Simulation/Aivika/Stream.hs
+++ b/Simulation/Aivika/Stream.hs
@@ -23,6 +23,8 @@
         splitStream,
         splitStreamQueueing,
         splitStreamPrioritising,
+        splitStreamFiltering,
+        splitStreamFilteringQueueing,
         -- * Specifying Identifier
         streamUsingId,
         -- * Prefetching and Delaying Stream
@@ -356,6 +358,45 @@
                           return a
                   return (a, stream ps)
      return $ map stream ps
+
+-- | Split the input stream into the specified number of output streams
+-- after filtering and applying the 'FCFS' strategy for enqueuing the output requests.
+splitStreamFiltering :: [a -> Event Bool] -> Stream a -> Simulation [Stream a]
+splitStreamFiltering = splitStreamFilteringQueueing FCFS
+
+-- | Split the input stream into the specified number of output streams after filtering.
+--
+-- If you don't know what the strategy to apply, then you probably
+-- need the 'FCFS' strategy, or function 'splitStreamFiltering' that
+-- does namely this.
+splitStreamFilteringQueueing :: EnqueueStrategy s
+                                => s
+                                -- ^ the strategy applied for enqueuing the output requests
+                                -> [a -> Event Bool]
+                                -- ^ the filters for output streams
+                                -> Stream a
+                                -- ^ the input stream
+                                -> Simulation [Stream a]
+                                -- ^ the splitted output streams
+splitStreamFilteringQueueing s preds x =
+  do ref <- liftIO $ newIORef x
+     res <- newResource s 1
+     let reader pred =
+           do a <-
+                usingResource res $
+                do p <- liftIO $ readIORef ref
+                   (a, xs) <- runStream p
+                   liftEvent $
+                     do f <- pred a
+                        if f
+                          then do liftIO $ writeIORef ref xs
+                                  return $ Just a
+                          else do liftIO $ writeIORef ref $ Cons (return (a, xs))
+                                  return Nothing
+              case a of
+                Just a  -> return a
+                Nothing -> reader pred
+     return $ map (repeatProcess . reader) preds
 
 -- | Concatenate the input streams applying the 'FCFS' strategy and
 -- producing one output stream.
diff --git a/aivika.cabal b/aivika.cabal
--- a/aivika.cabal
+++ b/aivika.cabal
@@ -1,5 +1,5 @@
 name:            aivika
-version:         4.3.1
+version:         4.3.2
 synopsis:        A multi-paradigm simulation library
 description:
     Aivika is a multi-paradigm simulation library with a strong emphasis
@@ -150,6 +150,7 @@
                      Simulation.Aivika.Parameter
                      Simulation.Aivika.Parameter.Random
                      Simulation.Aivika.PriorityQueue
+                     Simulation.Aivika.PriorityQueue.Pure
                      Simulation.Aivika.Process
                      Simulation.Aivika.Process.Random
                      Simulation.Aivika.Processor
