/// <summary>
        /// Set paddock inits for the surfaceOM component. Including stubble masses.
        /// </summary>
        /// <param name="apsimCompNode">SurfaceOM component in the paddock</param>
        /// <param name="paddock"></param>
        private void setSurfaceOMPaddockInits(XmlNode apsimCompNode, FarmPaddockType paddock)
        {
            // Stubble.
            //* this needs to be implemented with "wheat canola barley ... array of values
            // * - read in the values in each field and find the specified stubble type, set it, store it back
            // * 
            string stubbleType = paddock.StubbleType;
            if (stubbleType == null || stubbleType == "None")
                throw new Exception("No stubble type specified");

            FarmSoilType farmSoil = paddock.SoilType;
            OrgMatter stubble = new OrgMatter();
            XmlNode valueNode = apsimCompNode.SelectSingleNode("initdata/type");
            if (valueNode != null)
            {
                strToArray(ref stubble.types, valueNode.InnerText.ToLower());
                XmlNode nameNode = apsimCompNode.SelectSingleNode("initdata/name");
                strToArray(ref stubble.names, nameNode.InnerText.ToLower());
                XmlNode massNode = apsimCompNode.SelectSingleNode("initdata/mass");
                strToArray(ref stubble.masses, massNode.InnerText.ToLower());
                XmlNode cnrNode = apsimCompNode.SelectSingleNode("initdata/cnr");
                strToArray(ref stubble.cnrs, cnrNode.InnerText.ToLower());
                XmlNode sfNode = apsimCompNode.SelectSingleNode("initdata/standing_fraction");
                strToArray(ref stubble.stand_fract, sfNode.InnerText.ToLower());

                // check that all the residue types are listed that are in the crop rotation
                for (int crop = 0; crop < farmSoil.CropRotationList.Count; crop++)
                {
                    string cropName = farmSoil.CropRotationList[crop].Name.ToLower();
                    if (CropPhases.IsValidCropName(cropName) && (stubble.types.IndexOf(cropName) < 0))
                    {
                        //re-add the stubble with the correct values
                        stubble.names.Add(cropName);
                        stubble.types.Add(cropName);
                        stubble.masses.Add("0.0");
                        stubble.cnrs.Add("60.0");           // ?
                        stubble.stand_fract.Add("0.0");
                    }
                }

                int idx = stubble.types.IndexOf(paddock.StubbleType);       // if the stubble type exists in the list already
                if (idx >= 0)
                {
                    stubble.Remove(idx);
                }
                //remove all mass amounts
                for (int i = 0; i < stubble.masses.Count; i++)
                    stubble.masses[i] = "0.0";

                //re-add the stubble with the correct values
                stubble.names.Add(paddock.StubbleType);
                stubble.types.Add(paddock.StubbleType);
                stubble.masses.Add(paddock.StubbleMass.ToString());
                stubble.cnrs.Add(YieldProphetUtility.GetStubbleCNRatio(paddock.StubbleType).ToString());
                stubble.stand_fract.Add("0.0");

                valueNode.InnerText = APSIM.Shared.Utilities.StringUtilities.BuildString(stubble.types.ToArray(), "    ");
                nameNode.InnerText = APSIM.Shared.Utilities.StringUtilities.BuildString(stubble.names.ToArray(), "    ");
                massNode.InnerText = APSIM.Shared.Utilities.StringUtilities.BuildString(stubble.masses.ToArray(), "    ");
                cnrNode.InnerText = APSIM.Shared.Utilities.StringUtilities.BuildString(stubble.cnrs.ToArray(), "    ");
                sfNode.InnerText = APSIM.Shared.Utilities.StringUtilities.BuildString(stubble.stand_fract.ToArray(), "    ");
            }
        }
        /// <summary>
        /// Configure the pasture components in the paddock. Set the rooting depths.
        /// </summary>
        /// <param name="defaultPaddock"></param>
        /// <param name="depth">The cumulative soil depth</param>
        /// <param name="paddocknode">The padddock to set</param>
        private void SetPastureComponents(FarmPaddockType defaultPaddock, double depth, XmlNode paddocknode, FarmSoilType soilArea)
        {
            XmlNodeList pastureNodes = paddocknode.SelectNodes("component[attribute::class=\"Pasture\"]");
            foreach (XmlNode pastureNode in pastureNodes)
            {
                // get the current rooting depth from the pasture component in the simulation
                string sDepth = GetValue(pastureNode, "max_rtdep");
                double maxRtDep = (sDepth.Length > 0) ? Convert.ToDouble(sDepth) : 0;
                string simCompName = XmlUtilities.NameAttr(pastureNode);

                // find one that matches in the cropping rotation list and see if it specifies a new depth
                CropSpec pastureCrop = soilArea.CropRotationList.Find(c => c.Name.Equals(simCompName, StringComparison.InvariantCultureIgnoreCase));
                if (pastureCrop.MaxRootDepth > 0)
                {
                    maxRtDep = pastureCrop.MaxRootDepth;
                    SetValue(pastureNode, "max_rtdep", Math.Min(maxRtDep, depth * 0.95));       // allow up to 95% of soil depth
                }
                else
                {
                    if (maxRtDep > (depth * 0.95))                                              // this won't need setting if it is less than the limit
                        SetValue(pastureNode, "max_rtdep", Math.Min(maxRtDep, depth * 0.95));   // allow up to 95% of soil depth
                }
            }
        }
        /// <summary>
        /// Set the soilwat, soiln, surfaceom components
        /// </summary>
        /// <param name="defaultPaddock"></param>
        /// <param name="soilConfig"></param>
        /// <param name="paddocknode"></param>
        private void SetSoilComponents(FarmPaddockType defaultPaddock, Soil soilConfig, XmlNode paddocknode)
        {
            XmlNode apsimCompNode;
            XmlNode translatorNode;

            //set soilwat
            apsimCompNode = paddocknode.SelectSingleNode("system/component[@class=\"SoilWat\"]");
            initSoilWat(apsimCompNode, soilConfig);
            if (apsimCompNode != null)
            {
                translatorNode = apsimCompNode.ParentNode;
                initSoilWat_Trans(translatorNode, soilConfig, defaultPaddock.SoilType);
            }

            //set soiln
            apsimCompNode = paddocknode.SelectSingleNode("system/component[@class=\"SoilN\"]");
            initSoilN(apsimCompNode, soilConfig, defaultPaddock);
            if (apsimCompNode != null)
            {
                translatorNode = apsimCompNode.ParentNode;
                initSoilN_Trans(translatorNode, soilConfig);
            }

            //set surfaceOM
            apsimCompNode = paddocknode.SelectSingleNode("system/component[@class=\"SurfaceOM\"]");
            initSOM(apsimCompNode, soilConfig);
            if (apsimCompNode != null)
            {
                translatorNode = apsimCompNode.ParentNode;
                initSOM_Trans(translatorNode, soilConfig, defaultPaddock.SoilType);

                //if there is a paddock with init residue data and new crops in the rotation then set here 
                setSurfaceOMPaddockInits(apsimCompNode, defaultPaddock);
            }
        }
        /// <summary>
        /// Initialise a soiln component
        /// </summary>
        /// <param name="compNode"></param>
        /// <param name="aSoil"></param>
        private void initSoilN(XmlNode compNode, Soil aSoil, FarmPaddockType paddock)
        {
            XmlNode anode;
            anode = compNode.SelectSingleNode("initdata");
            XmlNode comment = simulationXMLNode.OwnerDocument.CreateComment(aSoil.Name);
            anode.AppendChild(comment);

            anode = compNode.SelectSingleNode("initdata/soiltype");
            anode.InnerText = aSoil.SoilType;

            anode = compNode.SelectSingleNode("initdata/root_cn");
            anode.InnerText = asApsimStr(aSoil.SoilOrganicMatter.RootCN);
            anode = compNode.SelectSingleNode("initdata/root_wt");
            anode.InnerText = asApsimStr(aSoil.SoilOrganicMatter.RootWt);
            anode = compNode.SelectSingleNode("initdata/soil_cn");
            anode.InnerText = asApsimStr(aSoil.SoilOrganicMatter.SoilCN);
            anode = compNode.SelectSingleNode("initdata/enr_a_coeff");
            anode.InnerText = asApsimStr(aSoil.SoilOrganicMatter.EnrACoeff);
            anode = compNode.SelectSingleNode("initdata/enr_b_coeff");
            anode.InnerText = asApsimStr(aSoil.SoilOrganicMatter.EnrBCoeff);
            anode = compNode.SelectSingleNode("initdata/profile_reduction");
            anode.InnerText = "off";

            anode = compNode.SelectSingleNode("initdata/oc");
            anode.InnerText = arrayAsStr(aSoil.SoilOrganicMatter.OC);
            anode = compNode.SelectSingleNode("initdata/ph");
            anode.InnerText = arrayAsStr(aSoil.Analysis.PH);
            anode = compNode.SelectSingleNode("initdata/fbiom");
            anode.InnerText = arrayAsStr(aSoil.SoilOrganicMatter.FBiom);
            anode = compNode.SelectSingleNode("initdata/finert");
            anode.InnerText = arrayAsStr(aSoil.SoilOrganicMatter.FInert);

            // set all the initial nitrogen values for this soiln
            double[] NH4Array = new double[aSoil.SoilWater.Thickness.Length];
            double[] NO3Array = new double[aSoil.SoilWater.Thickness.Length];
            for (int i = 0; i < NH4Array.Length; i++)
            {
                NH4Array[i] = 0.0;
                NO3Array[i] = 0.0;
            }
            if (paddock.Sample != null)
            {
                // be cautious and allow incomplete sample array sizes
                int i = 0;
                while ((i < paddock.Sample.NH4.Length) && (i < aSoil.SoilWater.Thickness.Length))
                {
                    NH4Array[i] = paddock.Sample.NH4[i];
                    i++;
                }
                i = 0;
                while ((i < paddock.Sample.NO3.Length) && (i < aSoil.SoilWater.Thickness.Length))
                {
                    NO3Array[i] = paddock.Sample.NO3[i];
                    i++;
                }
            }
            // these values are now set from the paddock soil Sample object
            anode = compNode.SelectSingleNode("initdata/no3ppm");
            anode.InnerText = arrayAsStr(NO3Array, "f3");
            anode = compNode.SelectSingleNode("initdata/nh4ppm");
            anode.InnerText = arrayAsStr(NH4Array, "f3");
        }