/// <summary>
        /// Saves the full-context label or mono align label into master label file.
        /// </summary>
        /// <param name="masterLabelFile">The file name of the master label file for full-context label.</param>
        /// <param name="typeOption">The given label type.</param>
        /// <param name="alignOption">The given alignment data.</param>
        /// <param name="keepRemainingPart">Whether to keep the remaining part.</param>
        public void Save(string masterLabelFile, LabelTypeOptions typeOption, LabelAlignOptions alignOption, bool keepRemainingPart)
        {
            using (StreamWriter writer = new StreamWriter(masterLabelFile, false, Encoding.ASCII))
            {
                writer.WriteLine(MasterLabelFileHeader);

                foreach (KeyValuePair<string, Sentence> kvp in _idKeyedSentences)
                {
                    writer.WriteLine(SentIdFormatString, kvp.Key);
                    kvp.Value.Save(writer, typeOption, alignOption, keepRemainingPart);
                    writer.WriteLine(Sentence.EndOfSentence);
                }
            }
        }
 /// <summary>
 /// Saves one sentence into master label file.
 /// </summary>
 /// <param name="writer">StreamWriter to save the sentence to.</param>
 /// <param name="typeOption">The given label type.</param>
 /// <param name="alignOption">The given alignment data.</param>
 /// <param name="keepRemainingPart">Whether to keep the remaining part.</param>
 public void Save(StreamWriter writer, LabelTypeOptions typeOption, LabelAlignOptions alignOption, bool keepRemainingPart)
 {
     foreach (PhoneSegment phoneSegment in _phoneSegments)
     {
         ICollection<string> result = phoneSegment.Save(typeOption, alignOption, keepRemainingPart);
         foreach (string line in result)
         {
             writer.WriteLine(line);
         }
     }
 }
        /// <summary>
        /// Converts the master label file to label files.
        /// </summary>
        /// <param name="mlfFileName">The name of target master label file.</param>
        /// <param name="alignmentDir">The directory of the alignment files.</param>
        /// <param name="alignOption">The given alignment data.</param>
        public static void ConvertMlfToLabelFiles(string mlfFileName, string alignmentDir, LabelAlignOptions alignOption)
        {
            TrainingSentenceSet set = new TrainingSentenceSet();
            set.Load(mlfFileName);

            foreach (KeyValuePair<string, Sentence> pair in set.Sentences)
            {
                string labelFile = FileExtensions.AppendExtensionName(pair.Key, FileExtensions.LabelFile);
                using (StreamWriter sw = new StreamWriter(Path.Combine(alignmentDir, labelFile)))
                {
                    pair.Value.Save(sw, LabelTypeOptions.FullContext, alignOption, true);
                }
            }
        }
        /// <summary>
        /// Saves the candidate into the lines in the format of master label file.
        /// </summary>
        /// <param name="typeOption">The given label type.</param>
        /// <param name="alignOption">The given alignment data.</param>
        /// <param name="keepRemainingPart">Whether to keep the remaining part.</param>
        /// <returns>The lines contains the candidate information.</returns>
        public string[] Save(LabelTypeOptions typeOption, LabelAlignOptions alignOption, bool keepRemainingPart)
        {
            if (alignOption == LabelAlignOptions.StateAlign)
            {
                string[] result = new string[StateAlignments.Length];
                for (int i = 0; i < StateAlignments.Length; ++i)
                {
                    LabelLine labelHelper = new LabelLine
                    {
                        Label = Label,
                        Segment = StateAlignments[i],
                        State = 2 + i
                    };

                    if (LabelRemainings != null && LabelRemainings.Count > 0)
                    {
                        labelHelper.Remaining = LabelRemainings[2 + i];
                    }

                    // Since Htk state index starts with 2.
                    result[i] = labelHelper.ToString(typeOption, keepRemainingPart);
                }

                return result;
            }

            LabelLine labelLine = new LabelLine { State = -1, Label = Label };
            if (LabelRemainings != null && LabelRemainings.Count > 0)
            {
                if (LabelRemainings.ContainsKey(-1))
                {
                    labelLine.Remaining = LabelRemainings[-1];
                }
                else if (LabelRemainings.ContainsKey(2))
                {
                    labelLine.Remaining = LabelRemainings[2];
                }
            }

            switch (alignOption)
            {
                case LabelAlignOptions.NoAlign:
                    labelLine.Segment = null;
                    break;
                case LabelAlignOptions.PhonemeAlign:
                    if (_stateSegments == null)
                    {
                        throw new InvalidOperationException("Unsupported operation since there is no alignment data in Candidate");
                    }

                    labelLine.Segment = new Segment(StartTime, EndTime);
                    break;
                default:
                    throw new InvalidDataException("Unknown HtkLabelAlignOptions value");
            }

            return new[] { labelLine.ToString(typeOption, keepRemainingPart) };
        }