// USE CASE: Creating a Document Definition from a FlexiLayout (*.afl)
        public static void Creating_a_Document_Definition_from_a_FlexiLayout(IEngine engine)
        {
            trace("Create a Document Definition from an *.afl file...");
            string flexibleDescriptionFilePath = SamplesFolder + "\\SampleMisc\\Invoice_eng.afl";
            IDocumentDefinition newDefinition  = engine.CreateDocumentDefinitionFromAFL(flexibleDescriptionFilePath, "English");

            // You can save the new Document Definition to a file or use it from memory
            traceBegin("Use the Document Definition in FlexiCaptureProcessor...");
            IFlexiCaptureProcessor processor = engine.CreateFlexiCaptureProcessor();

            processor.AddDocumentDefinition(newDefinition);

            // Add images for a single document
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Invoices_1.tif");

            // Recognize the document and check the result
            IDocument document = processor.RecognizeNextDocument();

            assert(document != null);
            assert(document.DocumentDefinition != null);
            assert(document.Pages.Count == 1);

            // Export the result
            processor.ExportDocumentEx(document, SamplesFolder + "\\FCEExport", "Invoice", null);
            traceEnd("OK");
        }
        // USE CASE: Creating a compound Document Definition
        public static void Creating_a_compound_Document_Definition(IEngine engine)
        {
            trace("Create an empty Document Definition in memory...");
            IDocumentDefinition newDefinition = engine.CreateDocumentDefinition();

            assert(newDefinition != null);

            trace("Set default language...");
            ILanguage language = engine.PredefinedLanguages.FindLanguage("English");

            assert(language != null);
            newDefinition.DefaultLanguage = language;

            trace("Create a new fixed section from an XFD file...");
            newDefinition.DefaultTextType = TextTypeEnum.TT_Handprinted;
            ISectionDefinition newSection1 = newDefinition.Sections.AddNew("Banking");

            newSection1.LoadXFDDescription(SamplesFolder + "\\SampleMisc\\Banking_eng.xfd");

            trace("Create a new flexible section from an AFL file...");
            newDefinition.DefaultTextType = TextTypeEnum.TT_Normal;
            ISectionDefinition newSection2 = newDefinition.Sections.AddNew("Invoice");

            newSection2.LoadFlexibleDescription(SamplesFolder + "\\SampleMisc\\Invoice_eng.afl");

            // Modify the template as required. In this sample we need to loosen some constraints
            IPageAnalysisParams analysisParams = engine.CreatePageAnalysisParams();

            analysisParams.CopyFrom(newDefinition.PageAnalysisParams);
            analysisParams.MaxHorizontalShrinkPercent = 20;
            analysisParams.MaxVerticalShrinkPercent   = 20;
            newDefinition.PageAnalysisParams          = analysisParams;

            trace("Check the Document Definition...");
            assert(newDefinition.Check() == true);

            // You can save the new Document Definition to a file or use it from memory
            traceBegin("Use the Document Definition in FlexiCaptureProcessor...");
            IFlexiCaptureProcessor processor = engine.CreateFlexiCaptureProcessor();

            processor.AddDocumentDefinition(newDefinition);

            // Add images for a single multipage document
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Banking_1.tif");
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Banking_2.tif");
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Banking_3.tif");
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Invoices_2.tif");
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Invoices_3.tif");

            // Recognize the document
            IDocument document = processor.RecognizeNextDocument();

            assert(document != null);
            assert(document.DocumentDefinition != null);
            assert(document.Pages.Count == 5);

            processor.ExportDocumentEx(document, SamplesFolder + "\\FCEExport", "Mixed", null);
            traceEnd("OK");
        }
        // USE CASE: Using image processing tools in custom preprocessing
        public static void Using_image_processing_tools_in_custom_preprocessing(IEngine engine)
        {
            trace("Create and configure an instance of FlexiCapture processor...");
            IFlexiCaptureProcessor processor = engine.CreateFlexiCaptureProcessor();

            processor.AddDocumentDefinitionFile(SamplesFolder + "\\SampleProject\\Templates\\Invoice_eng.fcdot");

            trace("Set up an image source with custom preprocessing...");
            // Create and configure sample image source. ALL PREPROCESSING IS DONE IN THE IMAGE SOURCE
            // (see SampleImageSource class for details)
            CustomPreprocessingImageSource imageSource = new CustomPreprocessingImageSource(engine);

            imageSource.AddImageFile(SamplesFolder + "\\SampleImages\\Invoices_1.tif");
            imageSource.AddImageFile(SamplesFolder + "\\SampleImages\\Invoices_2.tif");
            imageSource.AddImageFile(SamplesFolder + "\\SampleImages\\Invoices_3.tif");
            processor.SetCustomImageSource(imageSource);

            traceBegin("Process the images...");
            int count = 0;

            while (true)
            {
                IDocument document = processor.RecognizeNextDocument();
                if (document == null)
                {
                    IProcessingError error = processor.GetLastProcessingError();
                    assert(error == null);                       // No errors are expected in this sample
                    break;
                }
                else
                {
                    // We expect that this will never happen in this sample
                    assert(document.DocumentDefinition != null);
                }
                processor.ExportDocumentEx(document, SamplesFolder + "\\FCEExport", "NextDocument_" + count, null);
                count++;
            }
            traceEnd("OK");

            trace("Check the results...");
            assert(count == 2);
        }
        // USE CASE: Creating a Document Definition from an XML Form Definition
        public static void Creating_a_Document_Definition_from_an_XML_Form_Definition(IEngine engine)
        {
            trace("Create a Document Definition from an *.xfd file...");
            string formDescriptionFilePath    = SamplesFolder + "\\SampleMisc\\Banking_eng.xfd";
            IDocumentDefinition newDefinition = engine.CreateDocumentDefinitionFromXFD(formDescriptionFilePath, "English");

            // Modify the template as required. In this sample we need to loosen some constraints
            IPageAnalysisParams analysisParams = engine.CreatePageAnalysisParams();

            analysisParams.CopyFrom(newDefinition.PageAnalysisParams);
            analysisParams.MaxHorizontalShrinkPercent = 20;
            analysisParams.MaxVerticalShrinkPercent   = 20;
            newDefinition.PageAnalysisParams          = analysisParams;

            // You can save the new Document Definition to a file or use it from memory
            traceBegin("Use the Document Definition in FlexiCaptureProcessor...");
            IFlexiCaptureProcessor processor = engine.CreateFlexiCaptureProcessor();

            processor.AddDocumentDefinition(newDefinition);

            // Add images for a single multipage document
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Banking_1.tif");
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Banking_2.tif");
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Banking_3.tif");

            // Recognize the document and check the result
            IDocument document = processor.RecognizeNextDocument();

            assert(document != null);
            assert(document.DocumentDefinition != null);
            assert(document.Pages.Count == 3);

            // Export the result
            processor.ExportDocumentEx(document, SamplesFolder + "\\FCEExport", "Banking", null);
            traceEnd("OK");
        }
        // USE CASE: Configuring fields for better recognition results
        public static void Configuring_fields_for_better_recognition_results(IEngine engine)
        {
            trace("Create a Document Definition from a FlexiLayout...");
            IDocumentDefinition newDefinition = engine.CreateDocumentDefinitionFromAFL(SamplesFolder + "\\SampleMisc\\Invoice_eng.afl", "English");

            assert(newDefinition != null);

            trace("Configure data types...");
            setFieldValueType(newDefinition, "InvoiceDate", FieldValueTypeEnum.FVT_DateTime);
            setFieldValueType(newDefinition, "Quantity", FieldValueTypeEnum.FVT_Number);
            setFieldValueType(newDefinition, "UnitPrice", FieldValueTypeEnum.FVT_Currency);
            setFieldValueType(newDefinition, "Total", FieldValueTypeEnum.FVT_Currency);
            setFieldValueType(newDefinition, "TotalAmount", FieldValueTypeEnum.FVT_Currency);

            trace("Configure recognition languages for text fields ...");
            IFieldDefinition fieldDef = findFieldDef(newDefinition, "InvoiceNumber");

            assert(fieldDef != null);
            ITextRecognitionParams textParams = fieldDef.RecognitionParams.AsTextParams();
            ILanguage newLanguage             = textParams.CreateEmbeddedLanguageByDataType(FieldValueTypeEnum.FVT_DateTime);

            textParams.Language = newLanguage;

            newLanguage = textParams.CreateEmbeddedLanguage(textParams.Language.Type, textParams.Language);
            assert(newLanguage != textParams.Language);
            assert(newLanguage.LanguageCategory == LanguageCategoryEnum.LC_DataType);
            assert(newLanguage.DatatypeCategory == DatatypeCategoryEnum.TC_DateTime);
            textParams.Language = newLanguage;

            newLanguage = textParams.CreateEmbeddedLanguage(LanguageTypeEnum.LT_Group, null);
            newLanguage.AsGroupLanguage().Add(engine.PredefinedLanguages.FindLanguage("English"));
            newLanguage.AsGroupLanguage().Add(engine.PredefinedLanguages.FindLanguage("Russian"));
            textParams.Language = newLanguage;
            assert(textParams.Language.Type == LanguageTypeEnum.LT_Group);
            assert(textParams.Language.AsGroupLanguage().Count == 2);
            assert(textParams.Language.AsGroupLanguage().Item(0).InternalName == "English");
            assert(textParams.Language.AsGroupLanguage().Item(1).InternalName == "Russian");

            newLanguage = textParams.CreateEmbeddedLanguage(LanguageTypeEnum.LT_Simple, null);
            newLanguage.AsSimpleLanguage().set_LetterSet(LanguageLetterSetEnum.LLS_Alphabet, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
            newLanguage.AsSimpleLanguage().RegularExpression = "[A-Z]{1-}";
            textParams.Language = newLanguage;
            assert(textParams.Language.AsSimpleLanguage().RegularExpression.Length > 0);

            newLanguage = textParams.CreateEmbeddedLanguage(LanguageTypeEnum.LT_Simple, engine.PredefinedLanguages.FindLanguage("English"));
            assert(newLanguage.AsSimpleLanguage().UsePredefinedDictionary == true);
            assert(newLanguage.AsSimpleLanguage().UseUserDefinedDictionary == false);
            assert(newLanguage.AsSimpleLanguage().UserDefinedDictionary == null);
            newLanguage.AsSimpleLanguage().UseUserDefinedDictionary = true;
            FCEngine.IDictionary dictionary = newLanguage.AsSimpleLanguage().UserDefinedDictionary;
            assert(dictionary != null);
            assert(dictionary.WordsCount == 0);
            dictionary.AddWord("ONE", 1);
            dictionary.AddWord("TWO", 1);
            dictionary.AddWord("THREE", 1);
            assert(dictionary.WordsCount == 3);
            IEnumDictionaryWords enumWords = dictionary.EnumWords();

            for (int i = 0; i < 10; i++)
            {
                int    confidence = 0;
                string word       = enumWords.Next(out confidence);
                if (confidence == 0)
                {
                    break;
                }
                trace(word);
            }
            textParams.Language = newLanguage;

            trace("Check the Document Definition...");
            assert(newDefinition.Check() == true);

            traceBegin("Use the Document Definition in FlexiCaptureProcessor...");
            IFlexiCaptureProcessor processor = engine.CreateFlexiCaptureProcessor();

            processor.AddDocumentDefinition(newDefinition);

            // Add images for a single document
            processor.AddImageFile(SamplesFolder + "\\SampleImages\\Invoices_1.tif");

            // Recognize the document
            IDocument document = processor.RecognizeNextDocument();

            assert(document != null);
            assert(document.DocumentDefinition != null);
            assert(document.Pages.Count == 1);

            processor.ExportDocumentEx(document, SamplesFolder + "\\FCEExport", "Invoice", null);
            traceEnd("OK");
        }