/// <summary>
        /// Reads one HMM model instance from text reader instance.
        /// </summary>
        /// <param name="rewinder">Rewindable text reader instance to read HMM model from.</param>
        /// <param name="streams">Global HMM streams if any reference.</param>
        /// <param name="transition">Global transitions if any reference.</param>
        /// <returns>HMM model instance loaded.</returns>
        private static HmmModel ReadModel(RewindableTextReader rewinder,
            Dictionary<string, HmmStream> streams, Dictionary<string, Transition> transition)
        {
            Helper.ThrowIfNull(rewinder);
            Helper.ThrowIfNull(streams);
            Helper.ThrowIfNull(transition);
            HmmModel model = new HmmModel();

            Ensure(rewinder.ReadLine(), "<BEGINHMM>");

            int stateCount = ParseTagValue(rewinder.ReadLine(), "<NUMSTATES>");

            // Excludes the entrance and existing states
            for (int i = 1; i < stateCount - 1; i++)
            {
                HmmState state = ReadState(rewinder, streams);
                model.States.Add(state);
            }

            if (rewinder.PeekLine().StartsWith("~t"))
            {
                MacroName macro = MacroName.Create(rewinder.ReadLine());
                if (!transition.ContainsKey(macro.Name))
                {
                    throw new InvalidDataException(Helper.NeutralFormat("Transition [{0}] is not found.", macro.Name));
                }

                model.Transition = transition[macro.Name];
            }
            else if (rewinder.PeekLine().StartsWith("<TRANSP>"))
            {
                model.Transition = new Transition()
                {
                    Matrix = ReadTransition(rewinder),
                };
            }

            Ensure(rewinder.ReadLine(), "<ENDHMM>");

            return model;
        }
        /// <summary>
        /// Converts the HMM model instance into string in MMF format.
        /// </summary>
        /// <param name="model">The model instance to convert.</param>
        /// <param name="streams">The global streams to refer if any.</param>
        /// <param name="transitions">The global transitions to refer if any.</param>
        /// <returns>Model instance in string format.</returns>
        private static string ToString(HmmModel model,
            Dictionary<string, HmmStream> streams, Dictionary<string, Transition> transitions)
        {
            Helper.ThrowIfNull(model);
            Helper.ThrowIfNull(streams);
            Helper.ThrowIfNull(transitions);

            StringBuilder builder = new StringBuilder();

            if (model.Macro.Name.StartsWith("\"") || model.Macro.Name.EndsWith("\""))
            {
                throw new InvalidDataException(Helper.NeutralFormat(
                    "Macro name of model should not start or end with '\"', but it is [{0}].", model.Macro.Name));
            }

            builder.AppendFormat(CultureInfo.InvariantCulture,
                "~h \"{1}\"{0}", Environment.NewLine, model.Macro.Name);
            builder.AppendFormat(CultureInfo.InvariantCulture,
                "<BEGINHMM>{0}<NUMSTATES> {1}{0}", Environment.NewLine, model.States.Count + 2);

            if (model.States.Count == 0)
            {
                throw new InvalidDataException(Helper.NeutralFormat(
                    "There is not state in the model [{0}].", model.Macro.Name));
            }

            for (int i = 0; i < model.States.Count; i++)
            {
                builder.AppendFormat(CultureInfo.InvariantCulture, "<STATE> {1}{0}", Environment.NewLine, i + 2);
                for (int j = 0; j < model.States[i].Streams.Count; j++)
                {
                    if (streams.Values.Any(v => v == model.States[i].Streams[j]))
                    {
                        // References to the global stream instances.
                        builder.AppendFormat(CultureInfo.InvariantCulture,
                            "~s \"{1}\"{0}", Environment.NewLine, model.States[i].Streams[j].Name);
                    }
                    else
                    {
                        // Embeds the stream information into the local data.
                        builder.AppendFormat(CultureInfo.InvariantCulture,
                            "<STREAM> {1}{0}", Environment.NewLine, j + 1);
                        builder.AppendFormat(ToString(model.States[i].Streams[j]));
                    }
                }
            }

            if (model.Transition != null)
            {
                if (transitions.Values.Any(t => t == model.Transition))
                {
                    // References to the global transition instances.
                    builder.AppendFormat(CultureInfo.InvariantCulture,
                        "~t \"{1}\"{0}", Environment.NewLine, model.Transition.Macro.Name);
                }
                else
                {
                    // Embeds the transition into the local data.
                    builder.AppendFormat(ToString(model.Transition));
                }
            }

            builder.AppendLine("<ENDHMM>");

            return builder.ToString();
        }