public static OcrRecord GetOrCreate(string appId, Dictionary <string, OcrRecord> keeper)
        {
            if (keeper.ContainsKey(appId))
            {
                var prev = keeper[appId];
                return(prev);
            }

            var n = new OcrRecord()
            {
                AppID = appId
            };

            keeper[n.AppID] = n;
            return(n);
        }
        public void SaveFields(FilledForm form, List <OcrField> ocrFields, bool doOmr = false)
        {
            var sb = new StringBuilder();

            sb.Append($"OMR={doOmr}\n");
            sb.Append($"FormName: {form.Name}\n");
            sb.Append($"FileName: {form.FileName}\n");
            sb.Append(form.Master.Properties.Name + "\n");
            var fi = new FileInfo(form.FileName);

            Debug.Assert(fi.DirectoryName != null, "fi.DirectoryName != null");
            var outDir = Path.Combine(fi.DirectoryName, "data");

            EnsurePathExists(outDir);
            var fiMaster       = Path.GetFileNameWithoutExtension(form.Master.Properties.Name);
            var baseMergedName = Path.GetFileNameWithoutExtension(form.FileName) + "~" + fiMaster;
            var jsonMergedName = Path.Combine(outDir, baseMergedName + "_merged.json");

            var baseName = Path.GetFileNameWithoutExtension(form.FileName) + (doOmr ? "_omr" : "_ocr") + "~" + fiMaster;
            var image    = doOmr ? form.OmrImage : form.Image;

            Debug.Assert(outDir != null, "outDir != null");
            var imageName = Path.Combine(outDir, baseName + ".png");
            var jsonName  = Path.Combine(outDir, baseName + ".json");
            var jsonName2 = Path.Combine(outDir, baseName + "_short.json");

            var fieldInfo = Path.Combine(outDir, baseName + ".field_info");

            sb.Append($"imageName: {imageName}\n");
            sb.Append($"jsonName: {jsonName}\n");
            sb.Append($"jsonName2: {jsonName2}\n");
            sb.Append($"fieldInfo: {fieldInfo}\n");

            RasterCodecs.Save(image, imageName, RasterImageFormat.Png, 1);

            if (form.ProcessingPages?[0] != null)
            {
                var fields = new FormField[form.ProcessingPages[0].Count];
                int i      = 0;
                foreach (var field in form.ProcessingPages[0])
                {
                    fields[i++] = field;
                }

                sb.Append($"Json: {jsonName}");
                var json = JsonConvert.SerializeObject(fields, Formatting.Indented);
                File.WriteAllText(jsonName, json);
                sb.Append(json);
                OcrRecord curRecord = new OcrRecord();
                curRecord.AppID = AppID;
                curRecord.MasterForms.Add(form.Master.Properties.Name);
                sb = new StringBuilder();
                var jArray = Newtonsoft.Json.Linq.JArray.Parse(json);
                //Debug.WriteLine(jArray.Count);
                foreach (var jToken in jArray)
                {
                    var name   = jToken.Value <string>("Name");
                    var bounds = jToken.Value <string>("Bounds");
                    var res    = jToken["ResultDefault"];
                    if (res != null)
                    {
                        if (!doOmr)
                        {
                            var f = new OcrField(name, "text", bounds, res);
                            Debug.Assert(curRecord != null, nameof(curRecord) + " != null");
                            ocrFields.Add(f);
                            curRecord.AddField(f);
                        }
                    }
                    else
                    {
                        if (doOmr)
                        {
                            res = jToken["Result"];
                            var f = new OcrField(name, "omr", bounds, res);
                            Debug.Assert(curRecord != null, nameof(curRecord) + " != null");
                            ocrFields.Add(f);
                            curRecord.AddField(f);
                        }
                    }
                }
                File.WriteAllText(jsonName2,
                                  JsonConvert.SerializeObject(curRecord, Formatting.Indented));
                var fieldsSort = from o in ocrFields orderby o.VariableName select o;
                File.WriteAllText(jsonMergedName,
                                  JsonConvert.SerializeObject(fieldsSort.ToArray(), Formatting.Indented));
            }
            else
            {
                sb.Append("Json: No Fields found\n");
            }
            File.WriteAllText(fieldInfo, sb.ToString());
            logger.Info(sb.ToString());
        }