/// <summary>
        /// Parses the parameter from a RawProto.
        /// </summary>
        /// <param name="rp">Specifies the RawProto to parse.</param>
        /// <param name="p">Optionally, specifies an instance to load.  If <i>null</i>, a new instance is created and loaded.</param>
        /// <returns>A new instance of the parameter is returned.</returns>
        public static DataParameter FromProto(RawProto rp, DataParameter p = null)
        {
            string strVal;

            if (p == null)
            {
                p = new DataParameter();
            }

            if ((strVal = rp.FindValue("source")) != null)
            {
                p.source = strVal.Trim('\"');
            }

            if ((strVal = rp.FindValue("batch_size")) != null)
            {
                p.batch_size = uint.Parse(strVal);
            }

            if ((strVal = rp.FindValue("backend")) != null)
            {
                switch (strVal)
                {
                case "IMAGEDB":
                    p.backend = DB.IMAGEDB;
                    break;

                case "LMDB":
                    p.backend = DB.IMAGEDB;
                    break;

                case "NONE":
                    p.backend = DB.NONE;
                    break;

                default:
                    throw new Exception("Unknown 'backend' value " + strVal);
                }
            }

            if ((strVal = rp.FindValue("prefetch")) != null)
            {
                p.prefetch = uint.Parse(strVal);
            }

            if ((strVal = rp.FindValue("enable_random_selection")) != null)
            {
                p.enable_random_selection = bool.Parse(strVal);
            }

            if ((strVal = rp.FindValue("enable_pair_selection")) != null)
            {
                p.enable_pair_selection = bool.Parse(strVal);
            }

            if ((strVal = rp.FindValue("display_timing")) != null)
            {
                p.display_timing = bool.Parse(strVal);
            }

            if ((strVal = rp.FindValue("label_type")) != null)
            {
                switch (strVal)
                {
                case "SINGLE":
                    p.label_type = LABEL_TYPE.SINGLE;
                    break;

                case "MULTIPLE":
                    p.label_type = LABEL_TYPE.MULTIPLE;
                    break;

                default:
                    throw new Exception("Unknown 'label_type' value " + strVal);
                }
            }

            if ((strVal = rp.FindValue("primary_data")) != null)
            {
                p.primary_data = bool.Parse(strVal);
            }

            p.synchronize_with = rp.FindValue("synchronize_with");

            if ((strVal = rp.FindValue("synchronize_target")) != null)
            {
                p.synchronize_target = bool.Parse(strVal);
            }

            if ((strVal = rp.FindValue("images_per_blob")) != null)
            {
                p.images_per_blob = int.Parse(strVal);
            }

            if ((strVal = rp.FindValue("output_all_labels")) != null)
            {
                p.output_all_labels = bool.Parse(strVal);
            }

            if ((strVal = rp.FindValue("balance_matches")) != null)
            {
                p.balance_matches = bool.Parse(strVal);
            }

            if ((strVal = rp.FindValue("output_image_information")) != null)
            {
                p.output_image_information = bool.Parse(strVal);
            }

            if ((strVal = rp.FindValue("enable_noise_for_nonmatch")) != null)
            {
                p.enable_noise_for_nonmatch = bool.Parse(strVal);
            }

            RawProto rpDataNoise = rp.FindChild("data_noise_param");

            if (rpDataNoise != null)
            {
                p.data_noise_param = DataNoiseParameter.FromProto(rpDataNoise);
            }

            if ((strVal = rp.FindValue("enable_debug_output")) != null)
            {
                p.enable_debug_output = bool.Parse(strVal);
            }

            RawProto rpDataDebug = rp.FindChild("data_debug_param");

            if (rpDataDebug != null)
            {
                p.data_debug_param = DataDebugParameter.FromProto(rpDataDebug);
            }

            if ((strVal = rp.FindValue("forced_primary_label")) != null)
            {
                p.forced_primary_label = int.Parse(strVal);
            }

            if ((strVal = rp.FindValue("one_hot_label_size")) != null)
            {
                p.one_hot_label_size = int.Parse(strVal);
            }

            return(p);
        }