diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,11 @@
 
+Version 5.3
+-----
+
+* Introduced the result source titles, which can be useful when plotting the charts.
+
+* Added functions newSignalInTimeGrid and timeGrid.
+
 Version 5.2
 -----
 
diff --git a/Simulation/Aivika.hs b/Simulation/Aivika.hs
--- a/Simulation/Aivika.hs
+++ b/Simulation/Aivika.hs
@@ -42,8 +42,8 @@
         module Simulation.Aivika.Ref,
         module Simulation.Aivika.Resource.Base,
         module Simulation.Aivika.Results,
-        module Simulation.Aivika.Results.Locale,
         module Simulation.Aivika.Results.IO,
+        module Simulation.Aivika.Results.Locale,
         module Simulation.Aivika.Server,
         module Simulation.Aivika.Server.Random,
         module Simulation.Aivika.Signal,
@@ -90,8 +90,8 @@
 import Simulation.Aivika.Ref
 import Simulation.Aivika.Resource.Base
 import Simulation.Aivika.Results
-import Simulation.Aivika.Results.Locale
 import Simulation.Aivika.Results.IO
+import Simulation.Aivika.Results.Locale
 import Simulation.Aivika.Server
 import Simulation.Aivika.Server.Random
 import Simulation.Aivika.Signal
diff --git a/Simulation/Aivika/Internal/Process.hs b/Simulation/Aivika/Internal/Process.hs
--- a/Simulation/Aivika/Internal/Process.hs
+++ b/Simulation/Aivika/Internal/Process.hs
@@ -701,6 +701,10 @@
 --
 -- A cancellation of the child process doesn't lead to cancelling the parent process.
 -- Then 'Nothing' is returned within the computation.
+--
+-- This is a heavy-weight operation destined for working with arbitrary discontinuous
+-- processes. Please consider using a more light-weight function 'interruptProcess' or else
+-- 'cancelProcessWithId' whenever possible.
 timeoutProcess :: Double -> Process a -> Process (Maybe a)
 timeoutProcess timeout p =
   do pid <- liftSimulation newProcessId
@@ -716,6 +720,10 @@
 --
 -- A cancellation of the child process doesn't lead to cancelling the parent process.
 -- Then 'Nothing' is returned within the computation.
+--
+-- This is a heavy-weight operation destined for working with arbitrary discontinuous
+-- processes. Please consider using a more light-weight function 'interruptProcess' or else
+-- 'cancelProcessWithId' whenever possible.
 timeoutProcessUsingId :: Double -> ProcessId -> Process a -> Process (Maybe a)
 timeoutProcessUsingId timeout pid p =
   do s <- liftSimulation newSignalSource
diff --git a/Simulation/Aivika/Internal/Specs.hs b/Simulation/Aivika/Internal/Specs.hs
--- a/Simulation/Aivika/Internal/Specs.hs
+++ b/Simulation/Aivika/Internal/Specs.hs
@@ -27,6 +27,7 @@
         integPointsStartingFrom,
         integStartPoint,
         integStopPoint,
+        timeGrid,
         pointAt) where
 
 import Data.IORef
@@ -238,3 +239,15 @@
                            pointTime = basicTime sc n 0,
                            pointIteration = n,
                            pointPhase = 0 }
+
+-- | Return the indexed time values in the grid by specified size.
+timeGrid :: Specs -> Int -> [(Int, Double)]
+timeGrid sc n =
+  let t0 = spcStartTime sc
+      t2 = spcStopTime sc
+      n' = max (n - 1) 1
+      dt = (t2 - t0) / (fromIntegral n')
+      f i | i == 0    = (i, t0)
+          | i == n'   = (i, t2)
+          | otherwise = (i, t0 + (fromIntegral i) * dt)
+  in map f [0 .. n']
diff --git a/Simulation/Aivika/Results.hs b/Simulation/Aivika/Results.hs
--- a/Simulation/Aivika/Results.hs
+++ b/Simulation/Aivika/Results.hs
@@ -130,10 +130,7 @@
 import Simulation.Aivika.Resource
 import qualified Simulation.Aivika.Resource.Preemption as PR
 import Simulation.Aivika.Operation
-import Simulation.Aivika.Results.Locale
-
--- | A name used for indentifying the results when generating output.
-type ResultName = String
+import Simulation.Aivika.Results.Locale.Types
 
 -- | Represents a provider of the simulation results. It is usually something, or
 -- an array of something, or a list of such values which can be simulated to get data.
@@ -141,10 +138,18 @@
   
   -- | Return the source of simulation results by the specified name, description and provider. 
   resultSource :: ResultName -> ResultDescription -> p -> ResultSource
-  resultSource name descr = resultSource' name (UserDefinedResultId descr)
+  resultSource name descr = resultSource' name [name] i [i]
+    where i = (UserDefinedResultId $ UserDefinedResult name descr title)
+          title = resultNameToTitle name
+  
+  -- | Return the source of simulation results by the specified name, description, title and provider. 
+  resultSource3 :: ResultName -> ResultDescription -> ResultDescription -> p -> ResultSource
+  resultSource3 name descr title = resultSource' name [name] i [i]
+    where i = (UserDefinedResultId $ UserDefinedResult name descr title)
 
-  -- | Return the source of simulation results by the specified name, identifier and provider. 
-  resultSource' :: ResultName -> ResultId -> p -> ResultSource
+  -- | Return the source of simulation results by the specified name, its name path,
+  -- identifier, the corresponding indentifier path and provider. 
+  resultSource' :: ResultName -> [ResultName] -> ResultId -> [ResultId] -> p -> ResultSource
 
 -- | It associates the result sources with their names.
 type ResultSourceMap = M.Map ResultName ResultSource
@@ -167,10 +172,16 @@
 
   -- | The item name.
   resultItemName :: a -> ResultName
+
+  -- | The item name path.
+  resultItemNamePath :: a -> [ResultName]
   
   -- | The item identifier.
   resultItemId :: a -> ResultId
 
+  -- | The item identifier path.
+  resultItemIdPath :: a -> [ResultId]
+
   -- | Whether the item emits a signal.
   resultItemSignal :: a -> ResultSignal
 
@@ -419,8 +430,12 @@
 data ResultValue e =
   ResultValue { resultValueName :: ResultName,
                 -- ^ The value name.
+                resultValueNamePath :: [ResultName],
+                -- ^ The value name path.
                 resultValueId :: ResultId,
                 -- ^ The value identifier.
+                resultValueIdPath :: [ResultId],
+                -- ^ The value identifier path.
                 resultValueData :: ResultData e,
                 -- ^ Simulation data supplied by the value.
                 resultValueSignal :: ResultSignal
@@ -438,8 +453,12 @@
 data ResultContainer e =
   ResultContainer { resultContainerName :: ResultName,
                     -- ^ The container name.
+                    resultContainerNamePath :: [ResultName],
+                    -- ^ The container name path.
                     resultContainerId :: ResultId,
                     -- ^ The container identifier.
+                    resultContainerIdPath :: [ResultId],
+                    -- ^ The container identifier path.
                     resultContainerData :: e,
                     -- ^ The container data.
                     resultContainerSignal :: ResultSignal
@@ -467,7 +486,9 @@
   ResultItem $
   ResultValue {
     resultValueName   = (resultContainerName cont) ++ "." ++ name,
+    resultValueNamePath = (resultContainerNamePath cont) ++ [name],
     resultValueId     = i,
+    resultValueIdPath = (resultContainerIdPath cont) ++ [i],
     resultValueData   = f (resultContainerData cont),
     resultValueSignal = g (resultContainerData cont) }
 
@@ -550,7 +571,9 @@
 resultValueToContainer x =
   ResultContainer {
     resultContainerName   = resultValueName x,
+    resultContainerNamePath = resultValueNamePath x,
     resultContainerId     = resultValueId x,
+    resultContainerIdPath = resultValueIdPath x,
     resultContainerData   = resultValueData x,
     resultContainerSignal = resultValueSignal x }
 
@@ -559,7 +582,9 @@
 resultContainerToValue x =
   ResultValue {
     resultValueName   = resultContainerName x,
+    resultValueNamePath = resultContainerNamePath x,
     resultValueId     = resultContainerId x,
+    resultValueIdPath = resultContainerIdPath x,
     resultValueData   = resultContainerData x,
     resultValueSignal = resultContainerSignal x }
 
@@ -611,7 +636,9 @@
 instance ResultItemable (ResultValue Int) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = Just
@@ -632,7 +659,9 @@
 instance ResultItemable (ResultValue Double) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -653,7 +682,9 @@
 instance ResultItemable (ResultValue [Int]) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -674,7 +705,9 @@
 instance ResultItemable (ResultValue [Double]) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -695,7 +728,9 @@
 instance ResultItemable (ResultValue (SamplingStats Int)) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -716,7 +751,9 @@
 instance ResultItemable (ResultValue (SamplingStats Double)) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -737,7 +774,9 @@
 instance ResultItemable (ResultValue (TimingStats Int)) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -758,7 +797,9 @@
 instance ResultItemable (ResultValue (TimingStats Double)) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -779,7 +820,9 @@
 instance ResultItemable (ResultValue Bool) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -800,7 +843,9 @@
 instance ResultItemable (ResultValue String) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -821,7 +866,9 @@
 instance ResultItemable (ResultValue ()) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -842,7 +889,9 @@
 instance ResultItemable (ResultValue FCFS) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -863,7 +912,9 @@
 instance ResultItemable (ResultValue LCFS) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -884,7 +935,9 @@
 instance ResultItemable (ResultValue SIRO) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -905,7 +958,9 @@
 instance ResultItemable (ResultValue StaticPriorities) where
 
   resultItemName = resultValueName
+  resultItemNamePath = resultValueNamePath
   resultItemId = resultValueId
+  resultItemIdPath = resultValueIdPath
   resultItemSignal = resultValueSignal
   
   resultItemAsIntValue = const Nothing
@@ -1277,15 +1332,21 @@
 computeResultValue :: ResultComputing m
                       => ResultName
                       -- ^ the result name
+                      -> [ResultName]
+                      -- ^ the result name path
                       -> ResultId
                       -- ^ the result identifier
+                      -> [ResultId]
+                      -- ^ the result identifier path
                       -> m a
                       -- ^ the result computation
                       -> ResultValue a
-computeResultValue name i m =
+computeResultValue name names i is m =
   ResultValue {
     resultValueName   = name,
+    resultValueNamePath = names,
     resultValueId     = i,
+    resultValueIdPath = is,
     resultValueData   = computeResultData m,
     resultValueSignal = computeResultSignal m }
 
@@ -1864,7 +1925,7 @@
 
 -- | Return the source of the modeling time.
 timeResultSource :: ResultSource
-timeResultSource = resultSource' "t" TimeId time
+timeResultSource = resultSource' "t" ["t"] TimeId [TimeId] time
                          
 -- | Make an integer subscript
 intSubscript :: Int -> ResultName
@@ -1872,173 +1933,173 @@
 
 instance {-# OVERLAPPABLE #-} ResultItemable (ResultValue a) => ResultProvider (Parameter a) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ computeResultValue name names i is m
 
 instance {-# OVERLAPPABLE #-} ResultItemable (ResultValue a) => ResultProvider (Simulation a) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ computeResultValue name names i is m
 
 instance {-# OVERLAPPABLE #-} ResultItemable (ResultValue a) => ResultProvider (Dynamics a) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ computeResultValue name names i is m
 
 instance {-# OVERLAPPABLE #-} ResultItemable (ResultValue a) => ResultProvider (Event a) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ computeResultValue name names i is m
 
 instance {-# OVERLAPPABLE #-} ResultItemable (ResultValue a) => ResultProvider (Ref a) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ computeResultValue name names i is m
 
 instance {-# OVERLAPPABLE #-} ResultItemable (ResultValue a) => ResultProvider (BR.Ref a) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ computeResultValue name names i is m
 
 instance {-# OVERLAPPABLE #-} ResultItemable (ResultValue a) => ResultProvider (Var a) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ computeResultValue name names i is m
 
 instance {-# OVERLAPPABLE #-} ResultItemable (ResultValue a) => ResultProvider (Signalable a) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (SamplingStats a)))
                              => ResultProvider (Parameter (SamplingCounter a)) where
 
-  resultSource' name i m =
-    samplingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    samplingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (SamplingStats a)))
                              => ResultProvider (Simulation (SamplingCounter a)) where
 
-  resultSource' name i m =
-    samplingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    samplingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (SamplingStats a)))
                              => ResultProvider (Dynamics (SamplingCounter a)) where
 
-  resultSource' name i m =
-    samplingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    samplingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (SamplingStats a)))
                              => ResultProvider (Event (SamplingCounter a)) where
 
-  resultSource' name i m =
-    samplingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    samplingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (SamplingStats a)))
                              => ResultProvider (Ref (SamplingCounter a)) where
 
-  resultSource' name i m =
-    samplingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    samplingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (SamplingStats a)))
                              => ResultProvider (BR.Ref (SamplingCounter a)) where
 
-  resultSource' name i m =
-    samplingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    samplingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (SamplingStats a)))
                              => ResultProvider (Var (SamplingCounter a)) where
 
-  resultSource' name i m =
-    samplingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    samplingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (SamplingStats a)))
                              => ResultProvider (Signalable (SamplingCounter a)) where
 
-  resultSource' name i m =
-    samplingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    samplingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (TimingStats a)))
                              => ResultProvider (Parameter (TimingCounter a)) where
 
-  resultSource' name i m =
-    timingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    timingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (TimingStats a)))
                              => ResultProvider (Simulation (TimingCounter a)) where
 
-  resultSource' name i m =
-    timingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    timingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (TimingStats a)))
                              => ResultProvider (Dynamics (TimingCounter a)) where
 
-  resultSource' name i m =
-    timingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    timingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (TimingStats a)))
                              => ResultProvider (Event (TimingCounter a)) where
 
-  resultSource' name i m =
-    timingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    timingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (TimingStats a)))
                              => ResultProvider (Ref (TimingCounter a)) where
 
-  resultSource' name i m =
-    timingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    timingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (TimingStats a)))
                              => ResultProvider (BR.Ref (TimingCounter a)) where
 
-  resultSource' name i m =
-    timingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    timingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (TimingStats a)))
                              => ResultProvider (Var (TimingCounter a)) where
 
-  resultSource' name i m =
-    timingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    timingCounterResultSource $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (ResultItemable (ResultValue a),
                               ResultItemable (ResultValue (TimingStats a)))
                              => ResultProvider (Signalable (TimingCounter a)) where
 
-  resultSource' name i m =
-    timingCounterResultSource $ computeResultValue name i m
+  resultSource' name names i is m =
+    timingCounterResultSource $ computeResultValue name names i is m
 
 instance ResultProvider p => ResultProvider [p] where
 
-  resultSource' name i m =
-    resultSource' name i $ ResultListWithSubscript m subscript where
+  resultSource' name names i is m =
+    resultSource' name names i is $ ResultListWithSubscript m subscript where
       subscript = map snd $ zip m $ map intSubscript [0..]
 
 instance (Show i, Ix i, ResultProvider p) => ResultProvider (A.Array i p) where
 
-  resultSource' name i m =
-    resultSource' name i $ ResultListWithSubscript items subscript where
+  resultSource' name names i is m =
+    resultSource' name names i is $ ResultListWithSubscript items subscript where
       items = A.elems m
       subscript = map (\i -> "[" ++ show i ++ "]") (A.indices m)
 
 instance ResultProvider p => ResultProvider (V.Vector p) where
   
-  resultSource' name i m =
-    resultSource' name i $ ResultVectorWithSubscript m subscript where
+  resultSource' name names i is m =
+    resultSource' name names i is $ ResultVectorWithSubscript m subscript where
       subscript = V.imap (\i x -> intSubscript i) m
 
 -- | Represents a list with the specified subscript.
@@ -2055,7 +2116,7 @@
 
 instance ResultProvider p => ResultProvider (ResultListWithSubscript p) where
 
-  resultSource' name i (ResultListWithSubscript xs ys) =
+  resultSource' name names i is (ResultListWithSubscript xs ys) =
     ResultVectorSource $
     memoResultVectorSignal $
     memoResultVectorSummary $
@@ -2071,20 +2132,23 @@
       ays    = A.listArray bnds ys
       items  =
         flip map (zip ys xs) $ \(y, x) ->
-        let name' = name ++ y
-        in resultSource' name' (VectorItemId y) x
+        let name'  = name ++ y
+            names' = names ++ [y]
+            i'  = VectorItemId y
+            is' = is ++ [i']
+        in resultSource' name' names' i' is' x
       items' = map resultSourceSummary items
     
 instance (Show i, Ix i, ResultProvider p) => ResultProvider (ResultArrayWithSubscript i p) where
 
-  resultSource' name i (ResultArrayWithSubscript xs ys) =
-    resultSource' name i $ ResultListWithSubscript items subscript where
+  resultSource' name names i is (ResultArrayWithSubscript xs ys) =
+    resultSource' name names i is $ ResultListWithSubscript items subscript where
       items = A.elems xs
       subscript = A.elems ys
 
 instance ResultProvider p => ResultProvider (ResultVectorWithSubscript p) where
 
-  resultSource' name i (ResultVectorWithSubscript xs ys) =
+  resultSource' name names i is (ResultVectorWithSubscript xs ys) =
     ResultVectorSource $
     memoResultVectorSignal $
     memoResultVectorSummary $
@@ -2102,89 +2166,92 @@
         V.generate (V.length xs) $ \i ->
         let x = xs V.! i
             y = ys V.! i
-            name' = name ++ y
-        in resultSource' name' (VectorItemId y) x
+            name'  = name ++ y
+            names' = names ++ [y]
+            i'  = VectorItemId y
+            is' = is ++ [i']
+        in resultSource' name' names' i' is' x
       items' = V.map resultSourceSummary items
 
 instance {-# OVERLAPPING #-} (Ix i, Show i, ResultItemable (ResultValue [e])) => ResultProvider (Parameter (A.Array i e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (Ix i, Show i, ResultItemable (ResultValue [e])) => ResultProvider (Simulation (A.Array i e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (Ix i, Show i, ResultItemable (ResultValue [e])) => ResultProvider (Dynamics (A.Array i e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (Ix i, Show i, ResultItemable (ResultValue [e])) => ResultProvider (Event (A.Array i e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (Ix i, Show i, ResultItemable (ResultValue [e])) => ResultProvider (Ref (A.Array i e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (Ix i, Show i, ResultItemable (ResultValue [e])) => ResultProvider (BR.Ref (A.Array i e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (Ix i, Show i, ResultItemable (ResultValue [e])) => ResultProvider (Var (A.Array i e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} (Ix i, Show i, ResultItemable (ResultValue [e])) => ResultProvider (Signalable (A.Array i e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap A.elems $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} ResultItemable (ResultValue [e]) => ResultProvider (Parameter (V.Vector e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} ResultItemable (ResultValue [e]) => ResultProvider (Simulation (V.Vector e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} ResultItemable (ResultValue [e]) => ResultProvider (Dynamics (V.Vector e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} ResultItemable (ResultValue [e]) => ResultProvider (Event (V.Vector e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} ResultItemable (ResultValue [e]) => ResultProvider (Ref (V.Vector e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} ResultItemable (ResultValue [e]) => ResultProvider (BR.Ref (V.Vector e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} ResultItemable (ResultValue [e]) => ResultProvider (Var (V.Vector e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name names i is m
 
 instance {-# OVERLAPPING #-} ResultItemable (ResultValue [e]) => ResultProvider (Signalable (V.Vector e)) where
 
-  resultSource' name i m =
-    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name i m
+  resultSource' name names i is m =
+    ResultItemSource $ ResultItem $ fmap V.toList $ computeResultValue name names i is m
 
 instance (Show si, Show sm, Show so,
           ResultItemable (ResultValue si),
@@ -2192,43 +2259,43 @@
           ResultItemable (ResultValue so))
          => ResultProvider (Q.Queue si sm so a) where
 
-  resultSource' name i m =
-    queueResultSource $ ResultContainer name i m (ResultSignal $ Q.queueChanged_ m)
+  resultSource' name names i is m =
+    queueResultSource $ ResultContainer name names i is m (ResultSignal $ Q.queueChanged_ m)
 
 instance (Show sm, Show so,
           ResultItemable (ResultValue sm),
           ResultItemable (ResultValue so))
          => ResultProvider (IQ.Queue sm so a) where
 
-  resultSource' name i m =
-    infiniteQueueResultSource $ ResultContainer name i m (ResultSignal $ IQ.queueChanged_ m)
+  resultSource' name names i is m =
+    infiniteQueueResultSource $ ResultContainer name names i is m (ResultSignal $ IQ.queueChanged_ m)
 
 instance ResultProvider ArrivalTimer where
 
-  resultSource' name i m =
-    arrivalTimerResultSource $ ResultContainer name i m (ResultSignal $ arrivalProcessingTimeChanged_ m)
+  resultSource' name names i is m =
+    arrivalTimerResultSource $ ResultContainer name names i is m (ResultSignal $ arrivalProcessingTimeChanged_ m)
 
 instance (Show s, ResultItemable (ResultValue s)) => ResultProvider (Server s a b) where
 
-  resultSource' name i m =
-    serverResultSource $ ResultContainer name i m (ResultSignal $ serverChanged_ m)
+  resultSource' name names i is m =
+    serverResultSource $ ResultContainer name names i is m (ResultSignal $ serverChanged_ m)
 
 instance (Show s, ResultItemable (ResultValue s)) => ResultProvider (Activity s a b) where
 
-  resultSource' name i m =
-    activityResultSource $ ResultContainer name i m (ResultSignal $ activityChanged_ m)
+  resultSource' name names i is m =
+    activityResultSource $ ResultContainer name names i is m (ResultSignal $ activityChanged_ m)
 
 instance (Show s, ResultItemable (ResultValue s)) => ResultProvider (Resource s) where
 
-  resultSource' name i m =
-    resourceResultSource $ ResultContainer name i m (ResultSignal $ resourceChanged_ m)
+  resultSource' name names i is m =
+    resourceResultSource $ ResultContainer name names i is m (ResultSignal $ resourceChanged_ m)
 
 instance ResultProvider PR.Resource where
 
-  resultSource' name i m =
-    preemptibleResourceResultSource $ ResultContainer name i m (ResultSignal $ PR.resourceChanged_ m)
+  resultSource' name names i is m =
+    preemptibleResourceResultSource $ ResultContainer name names i is m (ResultSignal $ PR.resourceChanged_ m)
 
 instance ResultProvider (Operation a b) where
 
-  resultSource' name i m =
-    operationResultSource $ ResultContainer name i m (ResultSignal $ operationChanged_ m)
+  resultSource' name names i is m =
+    operationResultSource $ ResultContainer name names i is m (ResultSignal $ operationChanged_ m)
diff --git a/Simulation/Aivika/Results/IO.hs b/Simulation/Aivika/Results/IO.hs
--- a/Simulation/Aivika/Results/IO.hs
+++ b/Simulation/Aivika/Results/IO.hs
@@ -112,7 +112,7 @@
      liftIO $
        do hPutStr h tab
           hPutStr h "-- "
-          hPutStr h (loc $ resultItemId x)
+          hPutStr h (localiseResultDescription loc $ resultItemId x)
           hPutStrLn h ""
           hPutStr h tab
           hPutStr h label
@@ -124,7 +124,7 @@
      liftIO $
        do hPutStr h tab
           hPutStr h "-- "
-          hPutStr h (loc $ resultVectorId x)
+          hPutStr h (localiseResultDescription loc $ resultVectorId x)
           hPutStrLn h ""
           hPutStr h tab
           hPutStr h label
@@ -139,7 +139,7 @@
      liftIO $
        do hPutStr h tab
           hPutStr h "-- "
-          hPutStr h (loc $ resultObjectId x)
+          hPutStr h (localiseResultDescription loc $ resultObjectId x)
           hPutStrLn h ""
           hPutStr h tab
           hPutStr h label
@@ -228,7 +228,7 @@
      return $
        showString tab .
        showString "-- " .
-       showString (loc $ resultItemId x) .
+       showString (localiseResultDescription loc $ resultItemId x) .
        showString "\n" .
        showString tab .
        showString label .
@@ -246,7 +246,7 @@
      return $
        showString tab .
        showString "-- " .
-       showString (loc $ resultVectorId x) .
+       showString (localiseResultDescription loc $ resultVectorId x) .
        showString "\n" .
        showString tab .
        showString label .
@@ -265,7 +265,7 @@
      return $
        showString tab .
        showString "-- " .
-       showString (loc $ resultObjectId x) .
+       showString (localiseResultDescription loc $ resultObjectId x) .
        showString "\n" .
        showString tab .
        showString label .
diff --git a/Simulation/Aivika/Results/Locale.hs b/Simulation/Aivika/Results/Locale.hs
--- a/Simulation/Aivika/Results/Locale.hs
+++ b/Simulation/Aivika/Results/Locale.hs
@@ -12,480 +12,25 @@
 module Simulation.Aivika.Results.Locale
        (-- * Basic Types
         ResultLocale,
-        ResultLocalisation,
+        ResultLocalisation(..),
         ResultDescription,
+        UserDefinedResult(..),
+        LocalisedResult(..),
         -- * Locale Codes
         russianResultLocale,
         englishResultLocale,
         -- * Localisations
-        lookupResultLocalisation,
         russianResultLocalisation,
         englishResultLocalisation,
+        pathResultLocalisation,
+        localisePathResultDescription,
+        localisePathResultTitle,
+        lookupResultLocalisation,
         -- * Unique Identifiers
-        ResultId(..)) where
-
-import qualified Data.Map as M
-
-import Simulation.Aivika.Dynamics
-import Simulation.Aivika.Statistics
-import Simulation.Aivika.Statistics.Accumulator
-import qualified Simulation.Aivika.Queue as Q
-import qualified Simulation.Aivika.Queue.Infinite as IQ
-import Simulation.Aivika.Arrival
-import Simulation.Aivika.Server
-import Simulation.Aivika.Activity
-import Simulation.Aivika.Resource
-import Simulation.Aivika.Operation
-
--- | A locale to output the simulation results.
---
--- Examples are: @\"ru\", @\"en\" etc.
-type ResultLocale = String
-
--- | It localises the description of simulation results.
-type ResultLocalisation = ResultId -> ResultDescription
-
--- | A description used for describing the results when generating output.
-type ResultDescription = String
-
--- | The result entity identifier.
-data ResultId = TimeId
-                -- ^ A 'time' computation.
-              | VectorId
-                -- ^ Describes a vector.
-              | VectorItemId String
-                -- ^ Describes a vector item with the specified subscript.
-              | SamplingStatsId
-                -- ^ A 'SamplingStats' value.
-              | SamplingStatsCountId
-                -- ^ Property 'samplingStatsCount'.
-              | SamplingStatsMinId
-                -- ^ Property 'samplingStatsMin'.
-              | SamplingStatsMaxId
-                -- ^ Property 'samplingStatsMax'.
-              | SamplingStatsMeanId
-                -- ^ Property 'samplingStatsMean'.
-              | SamplingStatsMean2Id
-                -- ^ Property 'samplingStatsMean2'.
-              | SamplingStatsVarianceId
-                -- ^ Property 'samplingStatsVariance'.
-              | SamplingStatsDeviationId
-                -- ^ Property 'samplingStatsDeviation'.
-              | SamplingCounterId
-                -- ^ A 'SamplingCounter' value.
-              | SamplingCounterValueId
-                -- ^ Property 'samplingCounterValue'.
-              | SamplingCounterStatsId
-                -- ^ Property 'samplingCounterStats'.
-              | TimingStatsId
-                -- ^ A 'TimingStats' value.
-              | TimingStatsCountId
-                -- ^ Property 'timingStatsCount'.
-              | TimingStatsMinId
-                -- ^ Property 'timingStatsMin'.
-              | TimingStatsMaxId
-                -- ^ Property 'timingStatsMax'.
-              | TimingStatsMeanId
-                -- ^ Property 'timingStatsMean'.
-              | TimingStatsVarianceId
-                -- ^ Property 'timingStatsVariance'.
-              | TimingStatsDeviationId
-                -- ^ Property 'timingStatsDeviation'.
-              | TimingStatsMinTimeId
-                -- ^ Property 'timingStatsMinTime'.
-              | TimingStatsMaxTimeId
-                -- ^ Property 'timingStatsMaxTime'.
-              | TimingStatsStartTimeId
-                -- ^ Property 'timingStatsStartTime'.
-              | TimingStatsLastTimeId
-                -- ^ Property 'timingStatsLastTime'.
-              | TimingStatsSumId
-                -- ^ Property 'timingStatsSum'.
-              | TimingStatsSum2Id
-                -- ^ Property 'timingStatsSum2'.
-              | TimingCounterId
-                -- ^ A 'TimingCounter' value.
-              | TimingCounterValueId
-                -- ^ Property 'timingCounterValue'.
-              | TimingCounterStatsId
-                -- ^ Property 'timingCounterStats'.
-              | FiniteQueueId
-                -- ^ A finite 'Q.Queue'.
-              | InfiniteQueueId
-                -- ^ An infinite 'IQ.Queue'.
-              | EnqueueStrategyId
-                -- ^ Property 'Q.enqueueStrategy'.
-              | EnqueueStoringStrategyId
-                -- ^ Property 'Q.enqueueStoringStrategy'.
-              | DequeueStrategyId
-                -- ^ Property 'Q.dequeueStrategy'.
-              | QueueNullId
-                -- ^ Property 'Q.queueNull'.
-              | QueueFullId
-                -- ^ Property 'Q.queueFull'.
-              | QueueMaxCountId
-                -- ^ Property 'Q.queueMaxCount'.
-              | QueueCountId
-                -- ^ Property 'Q.queueCount'.
-              | QueueCountStatsId
-                -- ^ Property 'Q.queueCountStats'.
-              | EnqueueCountId
-                -- ^ Property 'Q.enqueueCount'.
-              | EnqueueLostCountId
-                -- ^ Property 'Q.enqueueLostCount'.
-              | EnqueueStoreCountId
-                -- ^ Property 'Q.enqueueStoreCount'.
-              | DequeueCountId
-                -- ^ Property 'Q.dequeueCount'.
-              | DequeueExtractCountId
-                -- ^ Property 'Q.dequeueExtractCount'.
-              | QueueLoadFactorId
-                -- ^ Property 'Q.queueLoadFactor'.
-              | EnqueueRateId
-                -- ^ Property 'Q.enqueueRate'.
-              | EnqueueStoreRateId
-                -- ^ Property 'Q.enqueueStoreRate'.
-              | DequeueRateId
-                -- ^ Property 'Q.dequeueRate'.
-              | DequeueExtractRateId
-                -- ^ Property 'Q.dequeueExtractRate'.
-              | QueueWaitTimeId
-                -- ^ Property 'Q.queueWaitTime'.
-              | QueueTotalWaitTimeId
-                -- ^ Property 'Q.queueTotalWaitTime'.
-              | EnqueueWaitTimeId
-                -- ^ Property 'Q.enqueueWaitTime'.
-              | DequeueWaitTimeId
-                -- ^ Property 'Q.dequeueWaitTime'.
-              | QueueRateId
-                -- ^ Property 'Q.queueRate'.
-              | ArrivalTimerId
-                -- ^ An 'ArrivalTimer'.
-              | ArrivalProcessingTimeId
-                -- ^ Property 'arrivalProcessingTime'.
-              | ServerId
-                -- ^ Represents a 'Server'.
-              | ServerInitStateId
-                -- ^ Property 'serverInitState'.
-              | ServerStateId
-                -- ^ Property 'serverState'.
-              | ServerTotalInputWaitTimeId
-                -- ^ Property 'serverTotalInputWaitTime'.
-              | ServerTotalProcessingTimeId
-                -- ^ Property 'serverTotalProcessingTime'.
-              | ServerTotalOutputWaitTimeId
-                -- ^ Property 'serverTotalOutputWaitTime'.
-              | ServerTotalPreemptionTimeId
-                -- ^ Property 'serverTotalPreemptionTime'.
-              | ServerInputWaitTimeId
-                -- ^ Property 'serverInputWaitTime'.
-              | ServerProcessingTimeId
-                -- ^ Property 'serverProcessingTime'.
-              | ServerOutputWaitTimeId
-                -- ^ Property 'serverOutputWaitTime'.
-              | ServerPreemptionTimeId
-                -- ^ Property 'serverPreemptionTime'.
-              | ServerInputWaitFactorId
-                -- ^ Property 'serverInputWaitFactor'.
-              | ServerProcessingFactorId
-                -- ^ Property 'serverProcessingFactor'.
-              | ServerOutputWaitFactorId
-                -- ^ Property 'serverOutputWaitFactor'.
-              | ServerPreemptionFactorId
-                -- ^ Property 'serverPreemptionFactor'.
-              | ActivityId
-                -- ^ Represents an 'Activity'.
-              | ActivityInitStateId
-                -- ^ Property 'activityInitState'.
-              | ActivityStateId
-                -- ^ Property 'activityState'.
-              | ActivityTotalUtilisationTimeId
-                -- ^ Property 'activityTotalUtilisationTime'.
-              | ActivityTotalIdleTimeId
-                -- ^ Property 'activityTotalIdleTime'.
-              | ActivityTotalPreemptionTimeId
-                -- ^ Property 'activityTotalPreemptionTime'.
-              | ActivityUtilisationTimeId
-                -- ^ Property 'activityUtilisationTime'.
-              | ActivityIdleTimeId
-                -- ^ Property 'activityIdleTime'.
-              | ActivityPreemptionTimeId
-                -- ^ Property 'activityPreemptionTime'.
-              | ActivityUtilisationFactorId
-                -- ^ Property 'activityUtilisationFactor'.
-              | ActivityIdleFactorId
-                -- ^ Property 'activityIdleFactor'.
-              | ActivityPreemptionFactorId
-                -- ^ Property 'activityPreemptionFactor'.
-              | ResourceId
-                -- ^ Represents a 'Resource'.
-              | ResourceCountId
-                -- ^ Property 'resourceCount'.
-              | ResourceCountStatsId
-                -- ^ Property 'resourceCountStats'.
-              | ResourceUtilisationCountId
-                -- ^ Property 'resourceUtilisationCount'.
-              | ResourceUtilisationCountStatsId
-                -- ^ Property 'resourceUtilisationCountStats'.
-              | ResourceQueueCountId
-                -- ^ Property 'resourceQueueCount'.
-              | ResourceQueueCountStatsId
-                -- ^ Property 'resourceQueueCountStats'.
-              | ResourceTotalWaitTimeId
-                -- ^ Property 'resourceTotalWaitTime'.
-              | ResourceWaitTimeId
-                -- ^ Property 'resourceWaitTime'.
-              | OperationId
-                -- ^ Represents an 'Operation'.
-              | OperationTotalUtilisationTimeId
-                -- ^ Property 'operationTotalUtilisationTime'.
-              | OperationTotalPreemptionTimeId
-                -- ^ Property 'operationTotalPreemptionTime'.
-              | OperationUtilisationTimeId
-                -- ^ Property 'operationUtilisationTime'.
-              | OperationPreemptionTimeId
-                -- ^ Property 'operationPreemptionTime'.
-              | OperationUtilisationFactorId
-                -- ^ Property 'operationUtilisationFactor'.
-              | OperationPreemptionFactorId
-                -- ^ Property 'operationPreemptionFactor'.
-              | UserDefinedResultId ResultDescription
-                -- ^ An user defined description.
-              | LocalisedResultId (M.Map ResultLocale ResultDescription)
-                -- ^ A localised property or object name.
-              deriving (Eq, Ord, Show)
-
--- | The Russian locale.
-russianResultLocale :: ResultLocale
-russianResultLocale = "ru"
-
--- | The English locale.
-englishResultLocale :: ResultLocale
-englishResultLocale = "en"
-
--- | The Russian localisation of the simulation results.
-russianResultLocalisation :: ResultLocalisation
-russianResultLocalisation TimeId = "модельное время"
-russianResultLocalisation VectorId = "вектор"
-russianResultLocalisation (VectorItemId x) = "элемент с индексом " ++ x
-russianResultLocalisation SamplingStatsId = "сводная статистика"
-russianResultLocalisation SamplingStatsCountId = "количество"
-russianResultLocalisation SamplingStatsMinId = "минимальное значение"
-russianResultLocalisation SamplingStatsMaxId = "максимальное значение"
-russianResultLocalisation SamplingStatsMeanId = "среднее значение"
-russianResultLocalisation SamplingStatsMean2Id = "среднее квадратов"
-russianResultLocalisation SamplingStatsVarianceId = "дисперсия"
-russianResultLocalisation SamplingStatsDeviationId = "среднеквадратическое отклонение"
-russianResultLocalisation TimingStatsId = "временная статистика"
-russianResultLocalisation TimingStatsCountId = "количество"
-russianResultLocalisation TimingStatsMinId = "минимальное значение"
-russianResultLocalisation TimingStatsMaxId = "максимальное значение"
-russianResultLocalisation TimingStatsMeanId = "среднее значение"
-russianResultLocalisation TimingStatsVarianceId = "дисперсия"
-russianResultLocalisation TimingStatsDeviationId = "среднеквадратическое отклонение"
-russianResultLocalisation TimingStatsMinTimeId = "время достижения минимума"
-russianResultLocalisation TimingStatsMaxTimeId = "время достижения максимума"
-russianResultLocalisation TimingStatsStartTimeId = "начальное время сбора статистики"
-russianResultLocalisation TimingStatsLastTimeId = "конечное время сбора статистики"
-russianResultLocalisation TimingStatsSumId = "сумма"
-russianResultLocalisation TimingStatsSum2Id = "сумма квадратов"
-russianResultLocalisation SamplingCounterId = "счетчик"
-russianResultLocalisation SamplingCounterValueId = "текущее значение"
-russianResultLocalisation SamplingCounterStatsId = "статистика"
-russianResultLocalisation TimingCounterId = "временной счетчик"
-russianResultLocalisation TimingCounterValueId = "текущее значение"
-russianResultLocalisation TimingCounterStatsId = "статистика"
-russianResultLocalisation FiniteQueueId = "конечная очередь"
-russianResultLocalisation InfiniteQueueId = "бесконечная очередь"
-russianResultLocalisation EnqueueStrategyId = "стратегия добавления элементов"
-russianResultLocalisation EnqueueStoringStrategyId = "стратегия хранения элементов"
-russianResultLocalisation DequeueStrategyId = "стратегия извлечения элементов"
-russianResultLocalisation QueueNullId = "очередь пуста?"
-russianResultLocalisation QueueFullId = "очередь заполнена?"
-russianResultLocalisation QueueMaxCountId = "емкость очереди"
-russianResultLocalisation QueueCountId = "текущий размер очереди"
-russianResultLocalisation QueueCountStatsId = "статистика по размеру очереди"
-russianResultLocalisation EnqueueCountId = "общее количество попыток добавить элементы"
-russianResultLocalisation EnqueueLostCountId = "общее количество неудачных попыток добавить элементы"
-russianResultLocalisation EnqueueStoreCountId = "общее количество сохраненных элементов"
-russianResultLocalisation DequeueCountId = "общее количество запросов на извлечение элементов"
-russianResultLocalisation DequeueExtractCountId = "общее количество извлеченных элементов"
-russianResultLocalisation QueueLoadFactorId = "коэфф. загрузки (размер, поделенный на емкость)"
-russianResultLocalisation EnqueueRateId = "количество попыток добавить на ед. времени"
-russianResultLocalisation EnqueueStoreRateId = "количество сохраненных на ед. времени"
-russianResultLocalisation DequeueRateId = "количество запросов на извлечение в ед. времени"
-russianResultLocalisation DequeueExtractRateId = "количество извлеченных на ед. времени"
-russianResultLocalisation QueueWaitTimeId = "время ожидания (сохранили -> извлекли)"
-russianResultLocalisation QueueTotalWaitTimeId = "общее время ожидания (попытались добавить -> извлекли)"
-russianResultLocalisation EnqueueWaitTimeId = "время ожидания добавления (попытались добавить -> сохранили)"
-russianResultLocalisation DequeueWaitTimeId = "время ожидания извлечения (запросили извлечь -> извлекли)"
-russianResultLocalisation QueueRateId = "усредненная скорость (как средняя длина очереди на среднее время ожидания)"
-russianResultLocalisation ArrivalTimerId = "как долго обрабатываются заявки?"
-russianResultLocalisation ArrivalProcessingTimeId = "время обработки заявки"
-russianResultLocalisation ServerId = "сервер"
-russianResultLocalisation ServerInitStateId = "начальное состояние"
-russianResultLocalisation ServerStateId = "текущее состояние"
-russianResultLocalisation ServerTotalInputWaitTimeId = "общее время блокировки в ожидании ввода"
-russianResultLocalisation ServerTotalProcessingTimeId = "общее время, потраченное на саму обработку заданий"
-russianResultLocalisation ServerTotalOutputWaitTimeId = "общее время блокировки при попытке доставить вывод"
-russianResultLocalisation ServerTotalPreemptionTimeId = "общее время вытеснения"
-russianResultLocalisation ServerInputWaitTimeId = "время блокировки в ожидании ввода"
-russianResultLocalisation ServerProcessingTimeId = "время, потраченное на саму обработку заданий"
-russianResultLocalisation ServerOutputWaitTimeId = "время блокировки при попытке доставить вывод"
-russianResultLocalisation ServerPreemptionTimeId = "время вытеснения"
-russianResultLocalisation ServerInputWaitFactorId = "относительное время блокировки в ожидании ввода (от 0 до 1)"
-russianResultLocalisation ServerProcessingFactorId = "относительное время, потраченное на саму обработку заданий (от 0 до 1)"
-russianResultLocalisation ServerOutputWaitFactorId = "относительное время блокировки при попытке доставить вывод (от 0 до 1)"
-russianResultLocalisation ServerPreemptionFactorId = "относительное время вытеснения (от 0 до 1)"
-russianResultLocalisation ActivityId = "активность"
-russianResultLocalisation ActivityInitStateId = "начальное состояние"
-russianResultLocalisation ActivityStateId = "текущее состояние"
-russianResultLocalisation ActivityTotalUtilisationTimeId = "общее время использования"
-russianResultLocalisation ActivityTotalIdleTimeId = "общее время простоя"
-russianResultLocalisation ActivityTotalPreemptionTimeId = "общее время вытеснения"
-russianResultLocalisation ActivityUtilisationTimeId = "статистика времени использования"
-russianResultLocalisation ActivityIdleTimeId = "статистика времени простоя"
-russianResultLocalisation ActivityPreemptionTimeId = "статистика времени вытеснения"
-russianResultLocalisation ActivityUtilisationFactorId = "относительное время использования (от 0 до 1)"
-russianResultLocalisation ActivityIdleFactorId = "относительное время простоя (от 0 до 1)"
-russianResultLocalisation ActivityPreemptionFactorId = "относительное время вытеснения (от 0 до 1)"
-russianResultLocalisation ResourceId = "ресурс"
-russianResultLocalisation ResourceCountId = "текущее доступное количество ресурса"
-russianResultLocalisation ResourceCountStatsId = "статистика по доступному количеству ресурса"
-russianResultLocalisation ResourceUtilisationCountId = "текущее используемое количество ресурса"
-russianResultLocalisation ResourceUtilisationCountStatsId = "статистика по используемому количеству ресурса"
-russianResultLocalisation ResourceQueueCountId = "текущая длина очереди к ресурсу"
-russianResultLocalisation ResourceQueueCountStatsId = "статистика длины очереди к ресурсу"
-russianResultLocalisation ResourceTotalWaitTimeId = "общее время ожидания ресурса"
-russianResultLocalisation ResourceWaitTimeId = "время ожидания ресурса"
-russianResultLocalisation OperationId = "операция"
-russianResultLocalisation OperationTotalUtilisationTimeId = "общее время использования"
-russianResultLocalisation OperationTotalPreemptionTimeId = "общее время вытеснения"
-russianResultLocalisation OperationUtilisationTimeId = "статистика времени использования"
-russianResultLocalisation OperationPreemptionTimeId = "статистика времени вытеснения"
-russianResultLocalisation OperationUtilisationFactorId = "относительное время использования (от 0 до 1)"
-russianResultLocalisation OperationPreemptionFactorId = "относительное время вытеснения (от 0 до 1)"
-russianResultLocalisation (UserDefinedResultId m) = m
-russianResultLocalisation x@(LocalisedResultId m) =
-  lookupResultLocalisation russianResultLocale x
-
--- | The English localisation of the simulation results.
-englishResultLocalisation :: ResultLocalisation
-englishResultLocalisation TimeId = "simulation time"
-englishResultLocalisation VectorId = "vector"
-englishResultLocalisation (VectorItemId x) = "item #" ++ x
-englishResultLocalisation SamplingStatsId = "statistics summary"
-englishResultLocalisation SamplingStatsCountId = "count"
-englishResultLocalisation SamplingStatsMinId = "minimum"
-englishResultLocalisation SamplingStatsMaxId = "maximum"
-englishResultLocalisation SamplingStatsMeanId = "mean"
-englishResultLocalisation SamplingStatsMean2Id = "mean square"
-englishResultLocalisation SamplingStatsVarianceId = "variance"
-englishResultLocalisation SamplingStatsDeviationId = "deviation"
-englishResultLocalisation TimingStatsId = "timing statistics"
-englishResultLocalisation TimingStatsCountId = "count"
-englishResultLocalisation TimingStatsMinId = "minimum"
-englishResultLocalisation TimingStatsMaxId = "maximum"
-englishResultLocalisation TimingStatsMeanId = "mean"
-englishResultLocalisation TimingStatsVarianceId = "variance"
-englishResultLocalisation TimingStatsDeviationId = "deviation"
-englishResultLocalisation TimingStatsMinTimeId = "the time of minimum"
-englishResultLocalisation TimingStatsMaxTimeId = "the time of maximum"
-englishResultLocalisation TimingStatsStartTimeId = "the start time"
-englishResultLocalisation TimingStatsLastTimeId = "the last time"
-englishResultLocalisation TimingStatsSumId = "sum"
-englishResultLocalisation TimingStatsSum2Id = "sum square"
-englishResultLocalisation SamplingCounterId = "counter"
-englishResultLocalisation SamplingCounterValueId = "current value"
-englishResultLocalisation SamplingCounterStatsId = "statistics"
-englishResultLocalisation TimingCounterId = "timing counter"
-englishResultLocalisation TimingCounterValueId = "current value"
-englishResultLocalisation TimingCounterStatsId = "statistics"
-englishResultLocalisation FiniteQueueId = "the finite queue"
-englishResultLocalisation InfiniteQueueId = "the infinite queue"
-englishResultLocalisation EnqueueStrategyId = "the enqueueing strategy"
-englishResultLocalisation EnqueueStoringStrategyId = "the storing strategy"
-englishResultLocalisation DequeueStrategyId = "the dequeueing strategy"
-englishResultLocalisation QueueNullId = "is the queue empty?"
-englishResultLocalisation QueueFullId = "is the queue full?"
-englishResultLocalisation QueueMaxCountId = "the queue capacity"
-englishResultLocalisation QueueCountId = "the current queue size"
-englishResultLocalisation QueueCountStatsId = "the queue size statistics"
-englishResultLocalisation EnqueueCountId = "a total number of attempts to enqueue the items"
-englishResultLocalisation EnqueueLostCountId = "a total number of the lost items when trying to enqueue"
-englishResultLocalisation EnqueueStoreCountId = "a total number of the stored items"
-englishResultLocalisation DequeueCountId = "a total number of requests for dequeueing"
-englishResultLocalisation DequeueExtractCountId = "a total number of the dequeued items"
-englishResultLocalisation QueueLoadFactorId = "the queue load (its size divided by its capacity)"
-englishResultLocalisation EnqueueRateId = "how many attempts to enqueue per time?"
-englishResultLocalisation EnqueueStoreRateId = "how many items were stored per time?"
-englishResultLocalisation DequeueRateId = "how many requests for dequeueing per time?"
-englishResultLocalisation DequeueExtractRateId = "how many items were dequeued per time?"
-englishResultLocalisation QueueWaitTimeId = "the wait time (stored -> dequeued)"
-englishResultLocalisation QueueTotalWaitTimeId = "the total wait time (tried to enqueue -> dequeued)"
-englishResultLocalisation EnqueueWaitTimeId = "the enqueue wait time (tried to enqueue -> stored)"
-englishResultLocalisation DequeueWaitTimeId = "the dequeue wait time (requested for dequeueing -> dequeued)"
-englishResultLocalisation QueueRateId = "the average queue rate (= queue size / wait time)"
-englishResultLocalisation ArrivalTimerId = "how long the arrivals are processed?"
-englishResultLocalisation ArrivalProcessingTimeId = "the processing time of arrivals"
-englishResultLocalisation ServerId = "the server"
-englishResultLocalisation ServerInitStateId = "the initial state"
-englishResultLocalisation ServerStateId = "the current state"
-englishResultLocalisation ServerTotalInputWaitTimeId = "the total time spent while waiting for input"
-englishResultLocalisation ServerTotalProcessingTimeId = "the total time spent on actual processing the tasks"
-englishResultLocalisation ServerTotalOutputWaitTimeId = "the total time spent on delivering the output"
-englishResultLocalisation ServerTotalPreemptionTimeId = "the total time spent being preempted"
-englishResultLocalisation ServerInputWaitTimeId = "the time spent while waiting for input"
-englishResultLocalisation ServerProcessingTimeId = "the time spent on processing the tasks"
-englishResultLocalisation ServerOutputWaitTimeId = "the time spent on delivering the output"
-englishResultLocalisation ServerPreemptionTimeId = "the time spent being preempted"
-englishResultLocalisation ServerInputWaitFactorId = "the relative time spent while waiting for input (from 0 to 1)"
-englishResultLocalisation ServerProcessingFactorId = "the relative time spent on processing the tasks (from 0 to 1)"
-englishResultLocalisation ServerOutputWaitFactorId = "the relative time spent on delivering the output (from 0 to 1)"
-englishResultLocalisation ServerPreemptionFactorId = "the relative time spent being preempted (from 0 to 1)"
-englishResultLocalisation ActivityId = "the activity"
-englishResultLocalisation ActivityInitStateId = "the initial state"
-englishResultLocalisation ActivityStateId = "the current state"
-englishResultLocalisation ActivityTotalUtilisationTimeId = "the total time of utilisation"
-englishResultLocalisation ActivityTotalIdleTimeId = "the total idle time"
-englishResultLocalisation ActivityTotalPreemptionTimeId = "the total time of preemption"
-englishResultLocalisation ActivityUtilisationTimeId = "the utilisation time"
-englishResultLocalisation ActivityIdleTimeId = "the idle time"
-englishResultLocalisation ActivityPreemptionTimeId = "the preemption time"
-englishResultLocalisation ActivityUtilisationFactorId = "the relative utilisation time (from 0 to 1)"
-englishResultLocalisation ActivityIdleFactorId = "the relative idle time (от 0 до 1)"
-englishResultLocalisation ActivityPreemptionFactorId = "the relative preemption time (from 0 to 1)"
-englishResultLocalisation ResourceId = "the resource"
-englishResultLocalisation ResourceCountId = "the current available count"
-englishResultLocalisation ResourceCountStatsId = "the available count statistics"
-englishResultLocalisation ResourceUtilisationCountId = "the current utilisation count"
-englishResultLocalisation ResourceUtilisationCountStatsId = "the utilisation count statistics"
-englishResultLocalisation ResourceQueueCountId = "the current queue length"
-englishResultLocalisation ResourceQueueCountStatsId = "the queue length statistics"
-englishResultLocalisation ResourceTotalWaitTimeId = "the total wait time"
-englishResultLocalisation ResourceWaitTimeId = "the wait time"
-englishResultLocalisation OperationId = "the operation"
-englishResultLocalisation OperationTotalUtilisationTimeId = "the total time of utilisation"
-englishResultLocalisation OperationTotalPreemptionTimeId = "the total time of preemption"
-englishResultLocalisation OperationUtilisationTimeId = "the utilisation time"
-englishResultLocalisation OperationPreemptionTimeId = "the preemption time"
-englishResultLocalisation OperationUtilisationFactorId = "the relative utilisation time (from 0 to 1)"
-englishResultLocalisation OperationPreemptionFactorId = "the relative preemption time (from 0 to 1)"
-englishResultLocalisation (UserDefinedResultId m) = m
-englishResultLocalisation x@(LocalisedResultId m) =
-  lookupResultLocalisation englishResultLocale x
+        ResultId(..),
+        -- * Utilities
+        resultNameToTitle) where
 
--- | Lookup a localisation by the specified locale.
-lookupResultLocalisation :: ResultLocale -> ResultLocalisation
-lookupResultLocalisation loc (UserDefinedResultId m) = m
-lookupResultLocalisation loc (LocalisedResultId m) =
-  case M.lookup loc m of
-    Just x -> x
-    Nothing ->
-      case M.lookup russianResultLocale m of
-        Just x -> x
-        Nothing ->
-          case M.lookup englishResultLocale m of
-            Just x -> x
-            Nothing -> ""
-lookupResultLocalisation loc resultId = russianResultLocalisation resultId
+import Simulation.Aivika.Results.Locale.Types
+import Simulation.Aivika.Results.Locale.Russian
+import Simulation.Aivika.Results.Locale.English
diff --git a/Simulation/Aivika/Results/Locale/English.hs b/Simulation/Aivika/Results/Locale/English.hs
new file mode 100644
--- /dev/null
+++ b/Simulation/Aivika/Results/Locale/English.hs
@@ -0,0 +1,231 @@
+
+-- |
+-- Module     : Simulation.Aivika.Results.Locale.English
+-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
+-- License    : BSD3
+-- Maintainer : David Sorokin <david.sorokin@gmail.com>
+-- Stability  : experimental
+-- Tested with: GHC 8.0.1
+--
+-- The English localisation.
+--
+module Simulation.Aivika.Results.Locale.English
+       (englishResultLocalisation) where
+
+import Simulation.Aivika.Results.Locale.Types
+
+-- | The English localisation.
+englishResultLocalisation :: ResultLocalisation
+englishResultLocalisation = ResultLocalisation englishResultDescription englishResultTitle
+
+-- | The English localisation of the simulation results.
+englishResultDescription :: ResultId -> ResultDescription
+englishResultDescription TimeId = "simulation time"
+englishResultDescription VectorId = "vector"
+englishResultDescription (VectorItemId x) = "item #" ++ x
+englishResultDescription SamplingStatsId = "statistics summary"
+englishResultDescription SamplingStatsCountId = "count"
+englishResultDescription SamplingStatsMinId = "minimum"
+englishResultDescription SamplingStatsMaxId = "maximum"
+englishResultDescription SamplingStatsMeanId = "mean"
+englishResultDescription SamplingStatsMean2Id = "mean square"
+englishResultDescription SamplingStatsVarianceId = "variance"
+englishResultDescription SamplingStatsDeviationId = "deviation"
+englishResultDescription TimingStatsId = "timing statistics"
+englishResultDescription TimingStatsCountId = "count"
+englishResultDescription TimingStatsMinId = "minimum"
+englishResultDescription TimingStatsMaxId = "maximum"
+englishResultDescription TimingStatsMeanId = "mean"
+englishResultDescription TimingStatsVarianceId = "variance"
+englishResultDescription TimingStatsDeviationId = "deviation"
+englishResultDescription TimingStatsMinTimeId = "the time of minimum"
+englishResultDescription TimingStatsMaxTimeId = "the time of maximum"
+englishResultDescription TimingStatsStartTimeId = "the start time"
+englishResultDescription TimingStatsLastTimeId = "the last time"
+englishResultDescription TimingStatsSumId = "sum"
+englishResultDescription TimingStatsSum2Id = "sum square"
+englishResultDescription SamplingCounterId = "counter"
+englishResultDescription SamplingCounterValueId = "current value"
+englishResultDescription SamplingCounterStatsId = "statistics"
+englishResultDescription TimingCounterId = "timing counter"
+englishResultDescription TimingCounterValueId = "current value"
+englishResultDescription TimingCounterStatsId = "statistics"
+englishResultDescription FiniteQueueId = "the finite queue"
+englishResultDescription InfiniteQueueId = "the infinite queue"
+englishResultDescription EnqueueStrategyId = "the enqueueing strategy"
+englishResultDescription EnqueueStoringStrategyId = "the storing strategy"
+englishResultDescription DequeueStrategyId = "the dequeueing strategy"
+englishResultDescription QueueNullId = "is the queue empty?"
+englishResultDescription QueueFullId = "is the queue full?"
+englishResultDescription QueueMaxCountId = "the queue capacity"
+englishResultDescription QueueCountId = "the current queue size"
+englishResultDescription QueueCountStatsId = "the queue size statistics"
+englishResultDescription EnqueueCountId = "a total number of attempts to enqueue the items"
+englishResultDescription EnqueueLostCountId = "a total number of the lost items when trying to enqueue"
+englishResultDescription EnqueueStoreCountId = "a total number of the stored items"
+englishResultDescription DequeueCountId = "a total number of requests for dequeueing"
+englishResultDescription DequeueExtractCountId = "a total number of the dequeued items"
+englishResultDescription QueueLoadFactorId = "the queue load (its size divided by its capacity)"
+englishResultDescription EnqueueRateId = "how many attempts to enqueue per time?"
+englishResultDescription EnqueueStoreRateId = "how many items were stored per time?"
+englishResultDescription DequeueRateId = "how many requests for dequeueing per time?"
+englishResultDescription DequeueExtractRateId = "how many items were dequeued per time?"
+englishResultDescription QueueWaitTimeId = "the wait time (stored -> dequeued)"
+englishResultDescription QueueTotalWaitTimeId = "the total wait time (tried to enqueue -> dequeued)"
+englishResultDescription EnqueueWaitTimeId = "the enqueue wait time (tried to enqueue -> stored)"
+englishResultDescription DequeueWaitTimeId = "the dequeue wait time (requested for dequeueing -> dequeued)"
+englishResultDescription QueueRateId = "the average queue rate (= queue size / wait time)"
+englishResultDescription ArrivalTimerId = "how long the arrivals are processed?"
+englishResultDescription ArrivalProcessingTimeId = "the processing time of arrivals"
+englishResultDescription ServerId = "the server"
+englishResultDescription ServerInitStateId = "the initial state"
+englishResultDescription ServerStateId = "the current state"
+englishResultDescription ServerTotalInputWaitTimeId = "the total time spent while waiting for input"
+englishResultDescription ServerTotalProcessingTimeId = "the total time spent on actual processing the tasks"
+englishResultDescription ServerTotalOutputWaitTimeId = "the total time spent on delivering the output"
+englishResultDescription ServerTotalPreemptionTimeId = "the total time spent being preempted"
+englishResultDescription ServerInputWaitTimeId = "the time spent while waiting for input"
+englishResultDescription ServerProcessingTimeId = "the time spent on processing the tasks"
+englishResultDescription ServerOutputWaitTimeId = "the time spent on delivering the output"
+englishResultDescription ServerPreemptionTimeId = "the time spent being preempted"
+englishResultDescription ServerInputWaitFactorId = "the relative time spent while waiting for input (from 0 to 1)"
+englishResultDescription ServerProcessingFactorId = "the relative time spent on processing the tasks (from 0 to 1)"
+englishResultDescription ServerOutputWaitFactorId = "the relative time spent on delivering the output (from 0 to 1)"
+englishResultDescription ServerPreemptionFactorId = "the relative time spent being preempted (from 0 to 1)"
+englishResultDescription ActivityId = "the activity"
+englishResultDescription ActivityInitStateId = "the initial state"
+englishResultDescription ActivityStateId = "the current state"
+englishResultDescription ActivityTotalUtilisationTimeId = "the total time of utilisation"
+englishResultDescription ActivityTotalIdleTimeId = "the total idle time"
+englishResultDescription ActivityTotalPreemptionTimeId = "the total time of preemption"
+englishResultDescription ActivityUtilisationTimeId = "the utilisation time"
+englishResultDescription ActivityIdleTimeId = "the idle time"
+englishResultDescription ActivityPreemptionTimeId = "the preemption time"
+englishResultDescription ActivityUtilisationFactorId = "the relative utilisation time (from 0 to 1)"
+englishResultDescription ActivityIdleFactorId = "the relative idle time (from 0 to 1)"
+englishResultDescription ActivityPreemptionFactorId = "the relative preemption time (from 0 to 1)"
+englishResultDescription ResourceId = "the resource"
+englishResultDescription ResourceCountId = "the current available count"
+englishResultDescription ResourceCountStatsId = "the available count statistics"
+englishResultDescription ResourceUtilisationCountId = "the current utilisation count"
+englishResultDescription ResourceUtilisationCountStatsId = "the utilisation count statistics"
+englishResultDescription ResourceQueueCountId = "the current queue length"
+englishResultDescription ResourceQueueCountStatsId = "the queue length statistics"
+englishResultDescription ResourceTotalWaitTimeId = "the total wait time"
+englishResultDescription ResourceWaitTimeId = "the wait time"
+englishResultDescription OperationId = "the operation"
+englishResultDescription OperationTotalUtilisationTimeId = "the total time of utilisation"
+englishResultDescription OperationTotalPreemptionTimeId = "the total time of preemption"
+englishResultDescription OperationUtilisationTimeId = "the utilisation time"
+englishResultDescription OperationPreemptionTimeId = "the preemption time"
+englishResultDescription OperationUtilisationFactorId = "the relative utilisation time (from 0 to 1)"
+englishResultDescription OperationPreemptionFactorId = "the relative preemption time (from 0 to 1)"
+englishResultDescription (UserDefinedResultId m) = userDefinedResultDescription m
+englishResultDescription (LocalisedResultId m) =
+  lookupResultLocalisation englishResultLocale (localisedResultDescriptions m)
+
+-- | The English localisation of titles.
+englishResultTitle :: ResultId -> ResultDescription
+englishResultTitle TimeId = "time"
+englishResultTitle VectorId = "vector"
+englishResultTitle (VectorItemId x) = "item #" ++ x
+englishResultTitle SamplingStatsId = "stats"
+englishResultTitle SamplingStatsCountId = "count"
+englishResultTitle SamplingStatsMinId = "minimum"
+englishResultTitle SamplingStatsMaxId = "maximum"
+englishResultTitle SamplingStatsMeanId = "mean"
+englishResultTitle SamplingStatsMean2Id = "mean square"
+englishResultTitle SamplingStatsVarianceId = "variance"
+englishResultTitle SamplingStatsDeviationId = "deviation"
+englishResultTitle TimingStatsId = "time-persistent stats"
+englishResultTitle TimingStatsCountId = "count"
+englishResultTitle TimingStatsMinId = "minimum"
+englishResultTitle TimingStatsMaxId = "maximum"
+englishResultTitle TimingStatsMeanId = "mean"
+englishResultTitle TimingStatsVarianceId = "variance"
+englishResultTitle TimingStatsDeviationId = "deviation"
+englishResultTitle TimingStatsMinTimeId = "time of minimum"
+englishResultTitle TimingStatsMaxTimeId = "time of maximum"
+englishResultTitle TimingStatsStartTimeId = "start time"
+englishResultTitle TimingStatsLastTimeId = "last time"
+englishResultTitle TimingStatsSumId = "sum"
+englishResultTitle TimingStatsSum2Id = "sum square"
+englishResultTitle SamplingCounterId = "stats counter"
+englishResultTitle SamplingCounterValueId = "current value"
+englishResultTitle SamplingCounterStatsId = "stats"
+englishResultTitle TimingCounterId = "time-persistent stats counter"
+englishResultTitle TimingCounterValueId = "current value"
+englishResultTitle TimingCounterStatsId = "time-persistent stats"
+englishResultTitle FiniteQueueId = "bounded queue"
+englishResultTitle InfiniteQueueId = "unbounded queue"
+englishResultTitle EnqueueStrategyId = "enqueu strategy"
+englishResultTitle EnqueueStoringStrategyId = "storing strategy"
+englishResultTitle DequeueStrategyId = "dequeue strategy"
+englishResultTitle QueueNullId = "empty queue?"
+englishResultTitle QueueFullId = "full queue?"
+englishResultTitle QueueMaxCountId = "queue capacity"
+englishResultTitle QueueCountId = "queue length"
+englishResultTitle QueueCountStatsId = "queue length stats"
+englishResultTitle EnqueueCountId = "enqueue request count"
+englishResultTitle EnqueueLostCountId = "failed enqueue count"
+englishResultTitle EnqueueStoreCountId = "fulfilled enqueue count"
+englishResultTitle DequeueCountId = "dequeue request count"
+englishResultTitle DequeueExtractCountId = "fulfilled dequeue count"
+englishResultTitle QueueLoadFactorId = "queue load"
+englishResultTitle EnqueueRateId = "enqueue request rate"
+englishResultTitle EnqueueStoreRateId = "fulfilled enqueue rate"
+englishResultTitle DequeueRateId = "dequeue request rate"
+englishResultTitle DequeueExtractRateId = "fulfilled dequeue rate"
+englishResultTitle QueueWaitTimeId = "wait time"
+englishResultTitle QueueTotalWaitTimeId = "total wait time"
+englishResultTitle EnqueueWaitTimeId = "enqueue wait time"
+englishResultTitle DequeueWaitTimeId = "dequeue wait time"
+englishResultTitle QueueRateId = "queue rate"
+englishResultTitle ArrivalTimerId = "measures arrival processing time"
+englishResultTitle ArrivalProcessingTimeId = "arrival processing time"
+englishResultTitle ServerId = "server"
+englishResultTitle ServerInitStateId = "initial state"
+englishResultTitle ServerStateId = "current state"
+englishResultTitle ServerTotalInputWaitTimeId = "total input wait time"
+englishResultTitle ServerTotalProcessingTimeId = "total processing time"
+englishResultTitle ServerTotalOutputWaitTimeId = "total output wait time"
+englishResultTitle ServerTotalPreemptionTimeId = "total preemption time"
+englishResultTitle ServerInputWaitTimeId = "input wait time"
+englishResultTitle ServerProcessingTimeId = "processing time"
+englishResultTitle ServerOutputWaitTimeId = "output wait time"
+englishResultTitle ServerPreemptionTimeId = "preemption time"
+englishResultTitle ServerInputWaitFactorId = "relative input wait time"
+englishResultTitle ServerProcessingFactorId = "relative processing time"
+englishResultTitle ServerOutputWaitFactorId = "relative output wait time"
+englishResultTitle ServerPreemptionFactorId = "relative preemption time"
+englishResultTitle ActivityId = "activity"
+englishResultTitle ActivityInitStateId = "initial state"
+englishResultTitle ActivityStateId = "current state"
+englishResultTitle ActivityTotalUtilisationTimeId = "total utilisation time"
+englishResultTitle ActivityTotalIdleTimeId = "total idle time"
+englishResultTitle ActivityTotalPreemptionTimeId = "total preemption time"
+englishResultTitle ActivityUtilisationTimeId = "utilisation time"
+englishResultTitle ActivityIdleTimeId = "idle time"
+englishResultTitle ActivityPreemptionTimeId = "preemption time"
+englishResultTitle ActivityUtilisationFactorId = "relative utilisation time"
+englishResultTitle ActivityIdleFactorId = "relative idle time"
+englishResultTitle ActivityPreemptionFactorId = "relative preemption time"
+englishResultTitle ResourceId = "resource"
+englishResultTitle ResourceCountId = "content"
+englishResultTitle ResourceCountStatsId = "content stats"
+englishResultTitle ResourceUtilisationCountId = "utilisation count"
+englishResultTitle ResourceUtilisationCountStatsId = "utilisation count stats"
+englishResultTitle ResourceQueueCountId = "queue length"
+englishResultTitle ResourceQueueCountStatsId = "queue length stats"
+englishResultTitle ResourceTotalWaitTimeId = "total wait time"
+englishResultTitle ResourceWaitTimeId = "wait time"
+englishResultTitle OperationId = "operation"
+englishResultTitle OperationTotalUtilisationTimeId = "total utilisation time"
+englishResultTitle OperationTotalPreemptionTimeId = "total preemption time"
+englishResultTitle OperationUtilisationTimeId = "utilisation time"
+englishResultTitle OperationPreemptionTimeId = "preemption time"
+englishResultTitle OperationUtilisationFactorId = "relative utilisation time"
+englishResultTitle OperationPreemptionFactorId = "relative preemption time"
+englishResultTitle (UserDefinedResultId m) = userDefinedResultTitle m
+englishResultTitle (LocalisedResultId m) =
+  lookupResultLocalisation englishResultLocale (localisedResultTitles m)
diff --git a/Simulation/Aivika/Results/Locale/Russian.hs b/Simulation/Aivika/Results/Locale/Russian.hs
new file mode 100644
--- /dev/null
+++ b/Simulation/Aivika/Results/Locale/Russian.hs
@@ -0,0 +1,231 @@
+
+-- |
+-- Module     : Simulation.Aivika.Results.Locale.Russian
+-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
+-- License    : BSD3
+-- Maintainer : David Sorokin <david.sorokin@gmail.com>
+-- Stability  : experimental
+-- Tested with: GHC 8.0.1
+--
+-- The Russian localisation.
+--
+module Simulation.Aivika.Results.Locale.Russian
+       (russianResultLocalisation) where
+
+import Simulation.Aivika.Results.Locale.Types
+
+-- | The Russian localisation.
+russianResultLocalisation :: ResultLocalisation
+russianResultLocalisation = ResultLocalisation russianResultDescription russianResultTitle
+
+-- | The Russian localisation of the simulation results.
+russianResultDescription :: ResultId -> ResultDescription
+russianResultDescription TimeId = "модельное время"
+russianResultDescription VectorId = "вектор"
+russianResultDescription (VectorItemId x) = "элемент с индексом " ++ x
+russianResultDescription SamplingStatsId = "сводная статистика"
+russianResultDescription SamplingStatsCountId = "количество"
+russianResultDescription SamplingStatsMinId = "минимальное значение"
+russianResultDescription SamplingStatsMaxId = "максимальное значение"
+russianResultDescription SamplingStatsMeanId = "среднее значение"
+russianResultDescription SamplingStatsMean2Id = "среднее квадратов"
+russianResultDescription SamplingStatsVarianceId = "дисперсия"
+russianResultDescription SamplingStatsDeviationId = "среднеквадратическое отклонение"
+russianResultDescription TimingStatsId = "временная статистика"
+russianResultDescription TimingStatsCountId = "количество"
+russianResultDescription TimingStatsMinId = "минимальное значение"
+russianResultDescription TimingStatsMaxId = "максимальное значение"
+russianResultDescription TimingStatsMeanId = "среднее значение"
+russianResultDescription TimingStatsVarianceId = "дисперсия"
+russianResultDescription TimingStatsDeviationId = "среднеквадратическое отклонение"
+russianResultDescription TimingStatsMinTimeId = "время достижения минимума"
+russianResultDescription TimingStatsMaxTimeId = "время достижения максимума"
+russianResultDescription TimingStatsStartTimeId = "начальное время сбора статистики"
+russianResultDescription TimingStatsLastTimeId = "конечное время сбора статистики"
+russianResultDescription TimingStatsSumId = "сумма"
+russianResultDescription TimingStatsSum2Id = "сумма квадратов"
+russianResultDescription SamplingCounterId = "счетчик"
+russianResultDescription SamplingCounterValueId = "текущее значение"
+russianResultDescription SamplingCounterStatsId = "статистика"
+russianResultDescription TimingCounterId = "временной счетчик"
+russianResultDescription TimingCounterValueId = "текущее значение"
+russianResultDescription TimingCounterStatsId = "статистика"
+russianResultDescription FiniteQueueId = "конечная очередь"
+russianResultDescription InfiniteQueueId = "бесконечная очередь"
+russianResultDescription EnqueueStrategyId = "стратегия добавления элементов"
+russianResultDescription EnqueueStoringStrategyId = "стратегия хранения элементов"
+russianResultDescription DequeueStrategyId = "стратегия извлечения элементов"
+russianResultDescription QueueNullId = "очередь пуста?"
+russianResultDescription QueueFullId = "очередь заполнена?"
+russianResultDescription QueueMaxCountId = "емкость очереди"
+russianResultDescription QueueCountId = "текущий размер очереди"
+russianResultDescription QueueCountStatsId = "статистика по размеру очереди"
+russianResultDescription EnqueueCountId = "общее количество попыток добавить элементы"
+russianResultDescription EnqueueLostCountId = "общее количество неудачных попыток добавить элементы"
+russianResultDescription EnqueueStoreCountId = "общее количество сохраненных элементов"
+russianResultDescription DequeueCountId = "общее количество запросов на извлечение элементов"
+russianResultDescription DequeueExtractCountId = "общее количество извлеченных элементов"
+russianResultDescription QueueLoadFactorId = "коэфф. загрузки (размер, поделенный на емкость)"
+russianResultDescription EnqueueRateId = "количество попыток добавить на ед. времени"
+russianResultDescription EnqueueStoreRateId = "количество сохраненных на ед. времени"
+russianResultDescription DequeueRateId = "количество запросов на извлечение в ед. времени"
+russianResultDescription DequeueExtractRateId = "количество извлеченных на ед. времени"
+russianResultDescription QueueWaitTimeId = "время ожидания (сохранили -> извлекли)"
+russianResultDescription QueueTotalWaitTimeId = "общее время ожидания (попытались добавить -> извлекли)"
+russianResultDescription EnqueueWaitTimeId = "время ожидания добавления (попытались добавить -> сохранили)"
+russianResultDescription DequeueWaitTimeId = "время ожидания извлечения (запросили извлечь -> извлекли)"
+russianResultDescription QueueRateId = "усредненная скорость (как средняя длина очереди на среднее время ожидания)"
+russianResultDescription ArrivalTimerId = "как долго обрабатываются заявки?"
+russianResultDescription ArrivalProcessingTimeId = "время обработки заявки"
+russianResultDescription ServerId = "сервер"
+russianResultDescription ServerInitStateId = "начальное состояние"
+russianResultDescription ServerStateId = "текущее состояние"
+russianResultDescription ServerTotalInputWaitTimeId = "общее время блокировки в ожидании ввода"
+russianResultDescription ServerTotalProcessingTimeId = "общее время, потраченное на саму обработку заданий"
+russianResultDescription ServerTotalOutputWaitTimeId = "общее время блокировки при попытке доставить вывод"
+russianResultDescription ServerTotalPreemptionTimeId = "общее время вытеснения"
+russianResultDescription ServerInputWaitTimeId = "время блокировки в ожидании ввода"
+russianResultDescription ServerProcessingTimeId = "время, потраченное на саму обработку заданий"
+russianResultDescription ServerOutputWaitTimeId = "время блокировки при попытке доставить вывод"
+russianResultDescription ServerPreemptionTimeId = "время вытеснения"
+russianResultDescription ServerInputWaitFactorId = "относительное время блокировки в ожидании ввода (от 0 до 1)"
+russianResultDescription ServerProcessingFactorId = "относительное время, потраченное на саму обработку заданий (от 0 до 1)"
+russianResultDescription ServerOutputWaitFactorId = "относительное время блокировки при попытке доставить вывод (от 0 до 1)"
+russianResultDescription ServerPreemptionFactorId = "относительное время вытеснения (от 0 до 1)"
+russianResultDescription ActivityId = "активность"
+russianResultDescription ActivityInitStateId = "начальное состояние"
+russianResultDescription ActivityStateId = "текущее состояние"
+russianResultDescription ActivityTotalUtilisationTimeId = "общее время использования"
+russianResultDescription ActivityTotalIdleTimeId = "общее время простоя"
+russianResultDescription ActivityTotalPreemptionTimeId = "общее время вытеснения"
+russianResultDescription ActivityUtilisationTimeId = "статистика времени использования"
+russianResultDescription ActivityIdleTimeId = "статистика времени простоя"
+russianResultDescription ActivityPreemptionTimeId = "статистика времени вытеснения"
+russianResultDescription ActivityUtilisationFactorId = "относительное время использования (от 0 до 1)"
+russianResultDescription ActivityIdleFactorId = "относительное время простоя (от 0 до 1)"
+russianResultDescription ActivityPreemptionFactorId = "относительное время вытеснения (от 0 до 1)"
+russianResultDescription ResourceId = "ресурс"
+russianResultDescription ResourceCountId = "текущее доступное количество ресурса"
+russianResultDescription ResourceCountStatsId = "статистика по доступному количеству ресурса"
+russianResultDescription ResourceUtilisationCountId = "текущее используемое количество ресурса"
+russianResultDescription ResourceUtilisationCountStatsId = "статистика по используемому количеству ресурса"
+russianResultDescription ResourceQueueCountId = "текущая длина очереди к ресурсу"
+russianResultDescription ResourceQueueCountStatsId = "статистика длины очереди к ресурсу"
+russianResultDescription ResourceTotalWaitTimeId = "общее время ожидания ресурса"
+russianResultDescription ResourceWaitTimeId = "время ожидания ресурса"
+russianResultDescription OperationId = "операция"
+russianResultDescription OperationTotalUtilisationTimeId = "общее время использования"
+russianResultDescription OperationTotalPreemptionTimeId = "общее время вытеснения"
+russianResultDescription OperationUtilisationTimeId = "статистика времени использования"
+russianResultDescription OperationPreemptionTimeId = "статистика времени вытеснения"
+russianResultDescription OperationUtilisationFactorId = "относительное время использования (от 0 до 1)"
+russianResultDescription OperationPreemptionFactorId = "относительное время вытеснения (от 0 до 1)"
+russianResultDescription (UserDefinedResultId m) = userDefinedResultDescription m
+russianResultDescription (LocalisedResultId m) =
+  lookupResultLocalisation russianResultLocale (localisedResultDescriptions m)
+
+-- | The Russian localisation of titles.
+russianResultTitle :: ResultId -> ResultDescription
+russianResultTitle TimeId = "время"
+russianResultTitle VectorId = "вектор"
+russianResultTitle (VectorItemId x) = "элемент с индексом " ++ x
+russianResultTitle SamplingStatsId = "статистика"
+russianResultTitle SamplingStatsCountId = "количество"
+russianResultTitle SamplingStatsMinId = "минимум"
+russianResultTitle SamplingStatsMaxId = "максимум"
+russianResultTitle SamplingStatsMeanId = "среднее"
+russianResultTitle SamplingStatsMean2Id = "среднее квадратов"
+russianResultTitle SamplingStatsVarianceId = "дисперсия"
+russianResultTitle SamplingStatsDeviationId = "отклонение"
+russianResultTitle TimingStatsId = "временная статистика"
+russianResultTitle TimingStatsCountId = "количество"
+russianResultTitle TimingStatsMinId = "минимум"
+russianResultTitle TimingStatsMaxId = "максимум"
+russianResultTitle TimingStatsMeanId = "среднее"
+russianResultTitle TimingStatsVarianceId = "дисперсия"
+russianResultTitle TimingStatsDeviationId = "отклонение"
+russianResultTitle TimingStatsMinTimeId = "время достижения минимума"
+russianResultTitle TimingStatsMaxTimeId = "время достижения максимума"
+russianResultTitle TimingStatsStartTimeId = "начальное время сбора статистики"
+russianResultTitle TimingStatsLastTimeId = "конечное время сбора статистики"
+russianResultTitle TimingStatsSumId = "сумма"
+russianResultTitle TimingStatsSum2Id = "сумма квадратов"
+russianResultTitle SamplingCounterId = "счетчик"
+russianResultTitle SamplingCounterValueId = "текущее значение"
+russianResultTitle SamplingCounterStatsId = "статистика"
+russianResultTitle TimingCounterId = "временной счетчик"
+russianResultTitle TimingCounterValueId = "текущее значение"
+russianResultTitle TimingCounterStatsId = "статистика"
+russianResultTitle FiniteQueueId = "конечная очередь"
+russianResultTitle InfiniteQueueId = "бесконечная очередь"
+russianResultTitle EnqueueStrategyId = "стратегия добавления элементов"
+russianResultTitle EnqueueStoringStrategyId = "стратегия хранения элементов"
+russianResultTitle DequeueStrategyId = "стратегия извлечения элементов"
+russianResultTitle QueueNullId = "очередь пуста?"
+russianResultTitle QueueFullId = "очередь заполнена?"
+russianResultTitle QueueMaxCountId = "емкость очереди"
+russianResultTitle QueueCountId = "длина очереди"
+russianResultTitle QueueCountStatsId = "статистика по длине очереди"
+russianResultTitle EnqueueCountId = "кол-во попыток добавить"
+russianResultTitle EnqueueLostCountId = "кол-во неудачных попыток добавить"
+russianResultTitle EnqueueStoreCountId = "кол-во сохраненных"
+russianResultTitle DequeueCountId = "кол-во запросов на извлечение"
+russianResultTitle DequeueExtractCountId = "кол-во извлеченных"
+russianResultTitle QueueLoadFactorId = "коэфф. загрузки"
+russianResultTitle EnqueueRateId = "кол-во попыток добавить на ед. времени"
+russianResultTitle EnqueueStoreRateId = "кол-во сохраненных на ед. времени"
+russianResultTitle DequeueRateId = "кол-во запросов на извлечение в ед. времени"
+russianResultTitle DequeueExtractRateId = "кол-во извлеченных на ед. времени"
+russianResultTitle QueueWaitTimeId = "время ожидания"
+russianResultTitle QueueTotalWaitTimeId = "общее время ожидания"
+russianResultTitle EnqueueWaitTimeId = "время ожидания добавления"
+russianResultTitle DequeueWaitTimeId = "время ожидания извлечения"
+russianResultTitle QueueRateId = "усредненная скорость"
+russianResultTitle ArrivalTimerId = "измеряет время обработки заявки"
+russianResultTitle ArrivalProcessingTimeId = "время обработки заявки"
+russianResultTitle ServerId = "сервер"
+russianResultTitle ServerInitStateId = "начальное состояние"
+russianResultTitle ServerStateId = "текущее состояние"
+russianResultTitle ServerTotalInputWaitTimeId = "общее время ожидания ввода"
+russianResultTitle ServerTotalProcessingTimeId = "общее время обработки"
+russianResultTitle ServerTotalOutputWaitTimeId = "общее время ожидания вывода"
+russianResultTitle ServerTotalPreemptionTimeId = "общее время вытеснения"
+russianResultTitle ServerInputWaitTimeId = "время ожидания ввода"
+russianResultTitle ServerProcessingTimeId = "время обработки"
+russianResultTitle ServerOutputWaitTimeId = "время ожидания вывода"
+russianResultTitle ServerPreemptionTimeId = "время вытеснения"
+russianResultTitle ServerInputWaitFactorId = "относит. время ожидания ввода"
+russianResultTitle ServerProcessingFactorId = "относит. время обработки"
+russianResultTitle ServerOutputWaitFactorId = "относит. время ожидания вывода"
+russianResultTitle ServerPreemptionFactorId = "относит. время вытеснения"
+russianResultTitle ActivityId = "активность"
+russianResultTitle ActivityInitStateId = "начальное состояние"
+russianResultTitle ActivityStateId = "текущее состояние"
+russianResultTitle ActivityTotalUtilisationTimeId = "общее время использования"
+russianResultTitle ActivityTotalIdleTimeId = "общее время простоя"
+russianResultTitle ActivityTotalPreemptionTimeId = "общее время вытеснения"
+russianResultTitle ActivityUtilisationTimeId = "время использования"
+russianResultTitle ActivityIdleTimeId = "время простоя"
+russianResultTitle ActivityPreemptionTimeId = "время вытеснения"
+russianResultTitle ActivityUtilisationFactorId = "относит. время использования"
+russianResultTitle ActivityIdleFactorId = "относит. время простоя"
+russianResultTitle ActivityPreemptionFactorId = "относит. время вытеснения"
+russianResultTitle ResourceId = "ресурс"
+russianResultTitle ResourceCountId = "текущее кол-во"
+russianResultTitle ResourceCountStatsId = "стат. по кол-ву"
+russianResultTitle ResourceUtilisationCountId = "текущее используемое кол-во"
+russianResultTitle ResourceUtilisationCountStatsId = "стат. по используемому кол-ву"
+russianResultTitle ResourceQueueCountId = "текущая длина очереди"
+russianResultTitle ResourceQueueCountStatsId = "стат. длины очереди"
+russianResultTitle ResourceTotalWaitTimeId = "общее время ожидания"
+russianResultTitle ResourceWaitTimeId = "время ожидания"
+russianResultTitle OperationId = "операция"
+russianResultTitle OperationTotalUtilisationTimeId = "общее время использования"
+russianResultTitle OperationTotalPreemptionTimeId = "общее время вытеснения"
+russianResultTitle OperationUtilisationTimeId = "стат. времени использования"
+russianResultTitle OperationPreemptionTimeId = "стат. времени вытеснения"
+russianResultTitle OperationUtilisationFactorId = "относит. время использования"
+russianResultTitle OperationPreemptionFactorId = "относит. время вытеснения"
+russianResultTitle (UserDefinedResultId m) = userDefinedResultTitle m
+russianResultTitle (LocalisedResultId m) =
+  lookupResultLocalisation russianResultLocale (localisedResultTitles m)
diff --git a/Simulation/Aivika/Results/Locale/Types.hs b/Simulation/Aivika/Results/Locale/Types.hs
new file mode 100644
--- /dev/null
+++ b/Simulation/Aivika/Results/Locale/Types.hs
@@ -0,0 +1,336 @@
+
+-- |
+-- Module     : Simulation.Aivika.Results.Locale.Types
+-- Copyright  : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>
+-- License    : BSD3
+-- Maintainer : David Sorokin <david.sorokin@gmail.com>
+-- Stability  : experimental
+-- Tested with: GHC 8.0.1
+--
+-- The module defines basic definitions for localisation.
+--
+module Simulation.Aivika.Results.Locale.Types
+       (-- * Basic Types
+        ResultLocale,
+        ResultLocalisation(..),
+        ResultName,
+        ResultDescription,
+        UserDefinedResult(..),
+        LocalisedResult(..),
+        -- * Locale Codes
+        russianResultLocale,
+        englishResultLocale,
+        -- * Localisations
+        pathResultLocalisation,
+        localisePathResultDescription,
+        localisePathResultTitle,
+        lookupResultLocalisation,
+        -- * Unique Identifiers
+        ResultId(..),
+        -- * Utilites
+        resultNameToTitle) where
+
+import Data.Char
+import Data.List
+import qualified Data.Map as M
+
+import Simulation.Aivika.Dynamics
+import Simulation.Aivika.Statistics
+import Simulation.Aivika.Statistics.Accumulator
+import qualified Simulation.Aivika.Queue as Q
+import qualified Simulation.Aivika.Queue.Infinite as IQ
+import Simulation.Aivika.Arrival
+import Simulation.Aivika.Server
+import Simulation.Aivika.Activity
+import Simulation.Aivika.Resource
+import Simulation.Aivika.Operation
+
+-- | A locale to output the simulation results.
+--
+-- Examples are: @\"ru\", @\"en\" etc.
+type ResultLocale = String
+
+-- | It localises the description and title of simulation results.
+data ResultLocalisation =
+  ResultLocalisation { localiseResultDescription :: ResultId -> ResultDescription,
+                       -- ^ Localise the description.
+                       localiseResultTitle :: ResultId -> ResultDescription
+                       -- ^ Localise the title.
+                     }
+
+-- | It describes the user-defined simulation result.
+data UserDefinedResult =
+  UserDefinedResult { userDefinedResultName :: ResultName,
+                      -- ^ The user-defined result name.
+                      userDefinedResultDescription :: ResultDescription,
+                      -- ^ The user-defined result description.
+                      userDefinedResultTitle :: ResultDescription
+                      -- ^ The user-defined result title.
+                    } deriving (Eq, Ord, Show)
+
+-- | This is a localisation of the specified simulation result.
+data LocalisedResult =
+  LocalisedResult { localisedResultDescriptions :: M.Map ResultLocale ResultDescription,
+                    -- ^ The localised descriptions.
+                    localisedResultTitles :: M.Map ResultLocale ResultDescription
+                    -- ^ The localised titles.
+                  } deriving (Eq, Ord, Show)
+
+-- | A name used for indentifying the results when generating output.
+type ResultName = String
+
+-- | A description used for describing the results when generating output.
+type ResultDescription = String
+
+-- | The result entity identifier.
+data ResultId = TimeId
+                -- ^ A 'time' computation.
+              | VectorId
+                -- ^ Describes a vector.
+              | VectorItemId String
+                -- ^ Describes a vector item with the specified subscript.
+              | SamplingStatsId
+                -- ^ A 'SamplingStats' value.
+              | SamplingStatsCountId
+                -- ^ Property 'samplingStatsCount'.
+              | SamplingStatsMinId
+                -- ^ Property 'samplingStatsMin'.
+              | SamplingStatsMaxId
+                -- ^ Property 'samplingStatsMax'.
+              | SamplingStatsMeanId
+                -- ^ Property 'samplingStatsMean'.
+              | SamplingStatsMean2Id
+                -- ^ Property 'samplingStatsMean2'.
+              | SamplingStatsVarianceId
+                -- ^ Property 'samplingStatsVariance'.
+              | SamplingStatsDeviationId
+                -- ^ Property 'samplingStatsDeviation'.
+              | SamplingCounterId
+                -- ^ A 'SamplingCounter' value.
+              | SamplingCounterValueId
+                -- ^ Property 'samplingCounterValue'.
+              | SamplingCounterStatsId
+                -- ^ Property 'samplingCounterStats'.
+              | TimingStatsId
+                -- ^ A 'TimingStats' value.
+              | TimingStatsCountId
+                -- ^ Property 'timingStatsCount'.
+              | TimingStatsMinId
+                -- ^ Property 'timingStatsMin'.
+              | TimingStatsMaxId
+                -- ^ Property 'timingStatsMax'.
+              | TimingStatsMeanId
+                -- ^ Property 'timingStatsMean'.
+              | TimingStatsVarianceId
+                -- ^ Property 'timingStatsVariance'.
+              | TimingStatsDeviationId
+                -- ^ Property 'timingStatsDeviation'.
+              | TimingStatsMinTimeId
+                -- ^ Property 'timingStatsMinTime'.
+              | TimingStatsMaxTimeId
+                -- ^ Property 'timingStatsMaxTime'.
+              | TimingStatsStartTimeId
+                -- ^ Property 'timingStatsStartTime'.
+              | TimingStatsLastTimeId
+                -- ^ Property 'timingStatsLastTime'.
+              | TimingStatsSumId
+                -- ^ Property 'timingStatsSum'.
+              | TimingStatsSum2Id
+                -- ^ Property 'timingStatsSum2'.
+              | TimingCounterId
+                -- ^ A 'TimingCounter' value.
+              | TimingCounterValueId
+                -- ^ Property 'timingCounterValue'.
+              | TimingCounterStatsId
+                -- ^ Property 'timingCounterStats'.
+              | FiniteQueueId
+                -- ^ A finite 'Q.Queue'.
+              | InfiniteQueueId
+                -- ^ An infinite 'IQ.Queue'.
+              | EnqueueStrategyId
+                -- ^ Property 'Q.enqueueStrategy'.
+              | EnqueueStoringStrategyId
+                -- ^ Property 'Q.enqueueStoringStrategy'.
+              | DequeueStrategyId
+                -- ^ Property 'Q.dequeueStrategy'.
+              | QueueNullId
+                -- ^ Property 'Q.queueNull'.
+              | QueueFullId
+                -- ^ Property 'Q.queueFull'.
+              | QueueMaxCountId
+                -- ^ Property 'Q.queueMaxCount'.
+              | QueueCountId
+                -- ^ Property 'Q.queueCount'.
+              | QueueCountStatsId
+                -- ^ Property 'Q.queueCountStats'.
+              | EnqueueCountId
+                -- ^ Property 'Q.enqueueCount'.
+              | EnqueueLostCountId
+                -- ^ Property 'Q.enqueueLostCount'.
+              | EnqueueStoreCountId
+                -- ^ Property 'Q.enqueueStoreCount'.
+              | DequeueCountId
+                -- ^ Property 'Q.dequeueCount'.
+              | DequeueExtractCountId
+                -- ^ Property 'Q.dequeueExtractCount'.
+              | QueueLoadFactorId
+                -- ^ Property 'Q.queueLoadFactor'.
+              | EnqueueRateId
+                -- ^ Property 'Q.enqueueRate'.
+              | EnqueueStoreRateId
+                -- ^ Property 'Q.enqueueStoreRate'.
+              | DequeueRateId
+                -- ^ Property 'Q.dequeueRate'.
+              | DequeueExtractRateId
+                -- ^ Property 'Q.dequeueExtractRate'.
+              | QueueWaitTimeId
+                -- ^ Property 'Q.queueWaitTime'.
+              | QueueTotalWaitTimeId
+                -- ^ Property 'Q.queueTotalWaitTime'.
+              | EnqueueWaitTimeId
+                -- ^ Property 'Q.enqueueWaitTime'.
+              | DequeueWaitTimeId
+                -- ^ Property 'Q.dequeueWaitTime'.
+              | QueueRateId
+                -- ^ Property 'Q.queueRate'.
+              | ArrivalTimerId
+                -- ^ An 'ArrivalTimer'.
+              | ArrivalProcessingTimeId
+                -- ^ Property 'arrivalProcessingTime'.
+              | ServerId
+                -- ^ Represents a 'Server'.
+              | ServerInitStateId
+                -- ^ Property 'serverInitState'.
+              | ServerStateId
+                -- ^ Property 'serverState'.
+              | ServerTotalInputWaitTimeId
+                -- ^ Property 'serverTotalInputWaitTime'.
+              | ServerTotalProcessingTimeId
+                -- ^ Property 'serverTotalProcessingTime'.
+              | ServerTotalOutputWaitTimeId
+                -- ^ Property 'serverTotalOutputWaitTime'.
+              | ServerTotalPreemptionTimeId
+                -- ^ Property 'serverTotalPreemptionTime'.
+              | ServerInputWaitTimeId
+                -- ^ Property 'serverInputWaitTime'.
+              | ServerProcessingTimeId
+                -- ^ Property 'serverProcessingTime'.
+              | ServerOutputWaitTimeId
+                -- ^ Property 'serverOutputWaitTime'.
+              | ServerPreemptionTimeId
+                -- ^ Property 'serverPreemptionTime'.
+              | ServerInputWaitFactorId
+                -- ^ Property 'serverInputWaitFactor'.
+              | ServerProcessingFactorId
+                -- ^ Property 'serverProcessingFactor'.
+              | ServerOutputWaitFactorId
+                -- ^ Property 'serverOutputWaitFactor'.
+              | ServerPreemptionFactorId
+                -- ^ Property 'serverPreemptionFactor'.
+              | ActivityId
+                -- ^ Represents an 'Activity'.
+              | ActivityInitStateId
+                -- ^ Property 'activityInitState'.
+              | ActivityStateId
+                -- ^ Property 'activityState'.
+              | ActivityTotalUtilisationTimeId
+                -- ^ Property 'activityTotalUtilisationTime'.
+              | ActivityTotalIdleTimeId
+                -- ^ Property 'activityTotalIdleTime'.
+              | ActivityTotalPreemptionTimeId
+                -- ^ Property 'activityTotalPreemptionTime'.
+              | ActivityUtilisationTimeId
+                -- ^ Property 'activityUtilisationTime'.
+              | ActivityIdleTimeId
+                -- ^ Property 'activityIdleTime'.
+              | ActivityPreemptionTimeId
+                -- ^ Property 'activityPreemptionTime'.
+              | ActivityUtilisationFactorId
+                -- ^ Property 'activityUtilisationFactor'.
+              | ActivityIdleFactorId
+                -- ^ Property 'activityIdleFactor'.
+              | ActivityPreemptionFactorId
+                -- ^ Property 'activityPreemptionFactor'.
+              | ResourceId
+                -- ^ Represents a 'Resource'.
+              | ResourceCountId
+                -- ^ Property 'resourceCount'.
+              | ResourceCountStatsId
+                -- ^ Property 'resourceCountStats'.
+              | ResourceUtilisationCountId
+                -- ^ Property 'resourceUtilisationCount'.
+              | ResourceUtilisationCountStatsId
+                -- ^ Property 'resourceUtilisationCountStats'.
+              | ResourceQueueCountId
+                -- ^ Property 'resourceQueueCount'.
+              | ResourceQueueCountStatsId
+                -- ^ Property 'resourceQueueCountStats'.
+              | ResourceTotalWaitTimeId
+                -- ^ Property 'resourceTotalWaitTime'.
+              | ResourceWaitTimeId
+                -- ^ Property 'resourceWaitTime'.
+              | OperationId
+                -- ^ Represents an 'Operation'.
+              | OperationTotalUtilisationTimeId
+                -- ^ Property 'operationTotalUtilisationTime'.
+              | OperationTotalPreemptionTimeId
+                -- ^ Property 'operationTotalPreemptionTime'.
+              | OperationUtilisationTimeId
+                -- ^ Property 'operationUtilisationTime'.
+              | OperationPreemptionTimeId
+                -- ^ Property 'operationPreemptionTime'.
+              | OperationUtilisationFactorId
+                -- ^ Property 'operationUtilisationFactor'.
+              | OperationPreemptionFactorId
+                -- ^ Property 'operationPreemptionFactor'.
+              | UserDefinedResultId UserDefinedResult
+                -- ^ An user defined description.
+              | LocalisedResultId LocalisedResult
+                -- ^ A localised property or object name.
+              deriving (Eq, Ord, Show)
+
+-- | The Russian locale.
+russianResultLocale :: ResultLocale
+russianResultLocale = "ru"
+
+-- | The English locale.
+englishResultLocale :: ResultLocale
+englishResultLocale = "en"
+
+-- | Lookup a localisation by the specified locale.
+lookupResultLocalisation :: ResultLocale -> M.Map ResultLocale ResultDescription -> ResultDescription
+lookupResultLocalisation loc m =
+  case M.lookup loc m of
+    Just x  -> x
+    Nothing ->
+      case M.lookup russianResultLocale m of
+        Just x  -> x
+        Nothing ->
+          case M.lookup englishResultLocale m of
+            Just x  -> x
+            Nothing -> ""
+
+-- | Return the path result localisation.
+pathResultLocalisation :: (ResultId -> ResultDescription) -> [ResultId] -> ResultDescription
+pathResultLocalisation loc is = loop is []
+  where loop [] acc                      = foldr ($) [] (reverse acc)
+        loop (x : xs) []                 = loop xs [(loc x ++)]
+        loop ((VectorItemId s) : xs) acc = loop xs $ (s ++) : (" " ++) : acc
+        loop (x : xs) acc                = loop xs $ (loc x ++) : (" / " ++) : acc
+
+-- | Localise the path result description.
+localisePathResultDescription :: ResultLocalisation -> [ResultId] -> ResultDescription
+localisePathResultDescription loc is = pathResultLocalisation (localiseResultDescription loc) is
+
+-- | Localise the path result title.
+localisePathResultTitle :: ResultLocalisation -> [ResultId] -> ResultDescription
+localisePathResultTitle loc is = pathResultLocalisation (localiseResultTitle loc) is
+
+-- | Convert the result name to title.
+resultNameToTitle :: ResultName -> ResultDescription
+resultNameToTitle =
+  unwords .
+  concat .
+  map (map $ map toLower) .
+  map (groupBy (\x y -> not $ isUpper y)) .
+  words
diff --git a/Simulation/Aivika/Signal.hs b/Simulation/Aivika/Signal.hs
--- a/Simulation/Aivika/Signal.hs
+++ b/Simulation/Aivika/Signal.hs
@@ -41,6 +41,7 @@
         newSignalInIntegTimes,
         newSignalInStartTime,
         newSignalInStopTime,
+        newSignalInTimeGrid,
         -- * Delaying Signal
         delaySignal,
         delaySignalM,
@@ -354,6 +355,18 @@
   do s <- liftSimulation newSignalSource
      t <- liftParameter stoptime
      enqueueEvent t $ triggerSignalWithCurrentTime s
+     return $ publishSignal s
+
+-- | Return a signal that is trigged in the grid by specified size.
+newSignalInTimeGrid :: Int -> Event (Signal Int)
+newSignalInTimeGrid n =
+  do sc <- liftParameter simulationSpecs
+     s  <- liftSimulation newSignalSource
+     let loop []            = return ()
+         loop ((i, t) : xs) = enqueueEvent t $
+                              do triggerSignal s i
+                                 loop xs
+     loop $ timeGrid sc n
      return $ publishSignal s
 
 -- | Describes a computation that also signals when changing its value.
diff --git a/Simulation/Aivika/Specs.hs b/Simulation/Aivika/Specs.hs
--- a/Simulation/Aivika/Specs.hs
+++ b/Simulation/Aivika/Specs.hs
@@ -20,6 +20,7 @@
         integPhaseBnds,
         integPhaseHiBnd,
         integPhaseLoBnd,
-        integTimes) where
+        integTimes,
+        timeGrid) where
 
 import Simulation.Aivika.Internal.Specs
diff --git a/Simulation/Aivika/Var.hs b/Simulation/Aivika/Var.hs
--- a/Simulation/Aivika/Var.hs
+++ b/Simulation/Aivika/Var.hs
@@ -12,6 +12,12 @@
 -- allows using the variable in differential and difference equations of
 -- System Dynamics within hybrid discrete-continuous simulation.
 --
+-- Because of using the arrays, it would usually be a logical mistake to
+-- use this variable for collecting statistics. In most cases,
+-- the statistics can actually be collected with a very small footprint
+-- by updating immutable 'SamplingStats' and 'TimingStats' values in
+-- a mutable 'Ref' reference.
+--
 module Simulation.Aivika.Var
        (Var,
         varChanged,
@@ -32,19 +38,25 @@
 import Simulation.Aivika.Internal.Event
 import Simulation.Aivika.Ref
 import Simulation.Aivika.Signal
+import Simulation.Aivika.Statistics
 
 import qualified Simulation.Aivika.Vector as V
 import qualified Simulation.Aivika.Vector.Unboxed as UV
 
 -- | Like the 'Ref' reference but keeps the history of changes in 
 -- different time points. The 'Var' variable is safe to be used in
--- the hybrid discrete-continuous simulation.
+-- the hybrid discrete-continuous simulation. Only this variable is
+-- much slower than the reference.
 --
--- For example, the memoised values of a variable can be used in
--- the differential or difference equations of System Dynamics, while
--- the variable iself can be updated wihin the discrete event simulation.
+-- For example, the memoised values of the variable can be used in
+-- the differential and difference equations of System Dynamics, while
+-- the variable iself can be updated within the discrete event simulation.
 --
--- Only this variable is much slower than the reference.
+-- Because of using arrays under the hood, it would usually be a logical
+-- mistake to use the variable for collecting statistics. In most cases,
+-- the statistics can actually be collected with a very small footprint
+-- by updating immutable 'SamplingStats' and 'TimingStats' values in
+-- a mutable @Ref@ reference.
 data Var a = 
   Var { varXS    :: UV.Vector Double,
         varMS    :: V.Vector a,
@@ -98,7 +110,7 @@
 
 -- | Read the recent actual value of a variable for the requested time.
 --
--- This computation is destined for using within discrete event simulation.
+-- This computation is destined to be used within discrete event simulation.
 readVar :: Var a -> Event a
 readVar v = 
   Event $ \p ->
@@ -162,7 +174,7 @@
                     V.appendVector ys $! b
                     invokeEvent p $ triggerSignal s b
 
--- | Freeze the variable and return in arrays the time points and corresponded 
+-- | Freeze the variable and return in arrays the time points and the corresponding 
 -- first and last values when the variable had changed or had been memoised in
 -- different time points: (1) the time points are sorted in ascending order;
 -- (2) the first and last actual values per each time point are provided.
diff --git a/Simulation/Aivika/Var/Unboxed.hs b/Simulation/Aivika/Var/Unboxed.hs
--- a/Simulation/Aivika/Var/Unboxed.hs
+++ b/Simulation/Aivika/Var/Unboxed.hs
@@ -12,6 +12,12 @@
 -- allows using the variable in differential and difference equations of
 -- System Dynamics within hybrid discrete-continuous simulation.
 --
+-- Because of using the arrays, it would usually be a logical mistake to
+-- use this variable for collecting statistics. In most cases,
+-- the statistics can actually be collected with a very small footprint
+-- by updating immutable 'SamplingStats' and 'TimingStats' values in
+-- a mutable 'Ref' reference.
+--
 module Simulation.Aivika.Var.Unboxed
        (Var,
         varChanged,
@@ -33,18 +39,24 @@
 import Simulation.Aivika.Ref
 import Simulation.Aivika.Signal
 import Simulation.Aivika.Unboxed
+import Simulation.Aivika.Statistics
 
 import qualified Simulation.Aivika.Vector.Unboxed as UV
 
 -- | Like the 'Ref' reference but keeps the history of changes in 
 -- different time points. The 'Var' variable is safe to be used in
--- the hybrid discrete-continuous simulation.
+-- the hybrid discrete-continuous simulation. Only this variable is
+-- much slower than the reference.
 --
--- For example, the memoised values of a variable can be used in
--- the differential or difference equations of System Dynamics, while
--- the variable iself can be updated wihin the discrete event simulation.
+-- For example, the memoised values of the variable can be used in
+-- the differential and difference equations of System Dynamics, while
+-- the variable iself can be updated within the discrete event simulation.
 --
--- Only this variable is much slower than the reference.
+-- Because of using arrays under the hood, it would usually be a logical
+-- mistake to use the variable for collecting statistics. In most cases,
+-- the statistics can actually be collected with a very small footprint
+-- by updating immutable 'SamplingStats' and 'TimingStats' values in
+-- a mutable @Ref@ reference.
 data Var a = 
   Var { varXS    :: UV.Vector Double,
         varMS    :: UV.Vector a,
@@ -98,7 +110,7 @@
 
 -- | Read the recent actual value of a variable for the requested time.
 --
--- This computation is destined for using within discrete event simulation.
+-- This computation is destined to be used within discrete event simulation.
 readVar :: Unboxed a => Var a -> Event a
 readVar v = 
   Event $ \p ->
@@ -162,7 +174,7 @@
                     UV.appendVector ys $! b
                     invokeEvent p $ triggerSignal s b
 
--- | Freeze the variable and return in arrays the time points and corresponded 
+-- | Freeze the variable and return in arrays the time points and the corresponding 
 -- first and last values when the variable had changed or had been memoised in
 -- different time points: (1) the time points are sorted in ascending order;
 -- (2) the first and last actual values per each time point are provided.
diff --git a/aivika.cabal b/aivika.cabal
--- a/aivika.cabal
+++ b/aivika.cabal
@@ -1,5 +1,5 @@
 name:            aivika
-version:         5.2
+version:         5.3
 synopsis:        A multi-method simulation library
 description:
     Aivika is a discrete event simulation (DES) framework with support of activity-oriented,
@@ -201,6 +201,9 @@
                      Simulation.Aivika.Resource.Preemption
                      Simulation.Aivika.Resource.Preemption.Base
                      Simulation.Aivika.Results.Locale
+                     Simulation.Aivika.Results.Locale.Russian
+                     Simulation.Aivika.Results.Locale.English
+                     Simulation.Aivika.Results.Locale.Types
                      Simulation.Aivika.Results.Transform
                      Simulation.Aivika.Results
                      Simulation.Aivika.Results.IO
diff --git a/examples/Furnace.hs b/examples/Furnace.hs
--- a/examples/Furnace.hs
+++ b/examples/Furnace.hs
@@ -48,7 +48,6 @@
 -- 4) utilization of the soaking pit furnace.
 
 import Data.Maybe
-import System.Random
 import Control.Monad
 import Control.Monad.Trans
 
