IRasterFunctionVariable myBandIndicesVar; // Variable for the Band Indices property.
        #endregion

        public NDVICustomFunctionUIClass()
        {
            myForm        = new NDVICustomFunctionUIForm();
            myArgs        = null;
            myPriority    = 100;
            myPageSite    = null;
            myHelpFile    = "";
            mySupportedID = new UIDClass();
            // The UID of the NDVICustomFunction object.
            mySupportedID.Value = "{" + "652642F3-9106-4EB3-9262-A4C39E03BC56" + "}";
            templateMode        = false;

            myRasterVar      = null;
            myBandIndicesVar = null;
        }
        IRasterFunctionVariable myBandIndicesVar; // Variable for the Band Indices property.
        #endregion

        public NDVICustomFunctionUIClass()
        {
            myForm = new NDVICustomFunctionUIForm();
            myArgs = null;
            myPriority = 100;
            myPageSite = null;
            myHelpFile = "";
            mySupportedID = new UIDClass();
            // The UID of the NDVICustomFunction object.
            mySupportedID.Value = "{" + "652642F3-9106-4EB3-9262-A4C39E03BC56" + "}";
            templateMode = false;

            myRasterVar = null;
            myBandIndicesVar = null;
        }
        /// <summary>
        /// Set the necessary objects required for the form. In this case
        /// the form is given an arguments object in edit mode, or is required
        /// to create one in create mode. After getting or creating the arguments
        /// object, template mode is checked for and handled. The template mode
        /// requires all parameters of the arguments object to converted to variables.
        /// </summary>
        /// <param name="objects">Set of objects required for the form.</param>
        public void SetObjects(ESRI.ArcGIS.esriSystem.ISet objects)
        {
            try
            {
                // Recurse through the objects
                objects.Reset();
                for (int i = 0; i < objects.Count; i++)
                {
                    object currObject = objects.Next();
                    // Find the properties to be set.
                    if (currObject is IPropertySet)
                    {
                        IPropertySet uiParameters = (IPropertySet)currObject;
                        object       names, values;
                        uiParameters.GetAllProperties(out names, out values);

                        bool disableForm = false;
                        try { disableForm = Convert.ToBoolean(uiParameters.GetProperty("RFxPropPageIsReadOnly")); }
                        catch (Exception) { }

                        if (disableForm)
                        {
                            isFormReadOnly = true;
                        }
                        else
                        {
                            isFormReadOnly = false;
                        }

                        // Check if the arguments object exists in the property set.
                        object functionArgument = null;
                        try { functionArgument = uiParameters.GetProperty("RFxArgument"); }
                        catch (Exception) { }
                        // If not, the form is in create mode.
                        if (functionArgument == null)
                        {
                            #region Create Mode
                            // Create a new arguments object.
                            myArgs = new NDVICustomFunctionArguments();
                            // Create a new property and set the arguments object on it.
                            uiParameters.SetProperty("RFxArgument", myArgs);
                            // Check if a default raster is supplied.
                            object defaultRaster = null;
                            try { defaultRaster = uiParameters.GetProperty("RFxDefaultInputRaster"); }
                            catch (Exception) { }
                            if (defaultRaster != null) // If it is, set it to the raster property.
                            {
                                myArgs.Raster = defaultRaster;
                            }
                            // Check if the form is in template mode.
                            templateMode = (bool)uiParameters.GetProperty("RFxTemplateEditMode");
                            if (templateMode)
                            {
                                // Since we are in create mode already, new variables have to be
                                // created for each property of the arguments object.
                                #region Create Variables
                                if (defaultRaster != null)
                                {
                                    // If a default raster is supplied and it is a variable,
                                    // there is no need to create one.
                                    if (defaultRaster is IRasterFunctionVariable)
                                    {
                                        myRasterVar = (IRasterFunctionVariable)defaultRaster;
                                    }
                                    else
                                    {
                                        // Create variable object for the InputRaster property.
                                        myRasterVar           = new RasterFunctionVariableClass();
                                        myRasterVar.Value     = defaultRaster;
                                        myRasterVar.Name      = "InputRaster";
                                        myRasterVar.IsDataset = true;
                                    }
                                }

                                // Create a variable for the BandIndices property.
                                myBandIndicesVar      = new RasterFunctionVariableClass();
                                myBandIndicesVar.Name = "BandIndices";
                                // Use the default value from the arguments object
                                myBandIndicesVar.Value = myArgs.BandIndices;

                                // Set the variables created as properties on the arguments object.
                                IRasterFunctionArguments rasterFunctionArgs =
                                    (IRasterFunctionArguments)myArgs;
                                rasterFunctionArgs.PutValue("Raster", myRasterVar);
                                rasterFunctionArgs.PutValue("BandIndices", myBandIndicesVar);
                                #endregion
                            }
                            #endregion
                        }
                        else
                        {
                            #region  Edit Mode
                            // Get the arguments object from the property set.
                            myArgs = (INDVICustomFunctionArguments)functionArgument;
                            // Check if the form is in template mode.
                            templateMode = (bool)uiParameters.GetProperty("RFxTemplateEditMode");
                            if (templateMode)
                            {
                                #region Edit Template
                                // In template edit mode, the variables from the arguments object
                                // are extracted.
                                IRasterFunctionArguments rasterFunctionArgs =
                                    (IRasterFunctionArguments)myArgs;
                                object raster = rasterFunctionArgs.GetValue("Raster");

                                // Create or Open the Raster variable.
                                if (raster is IRasterFunctionVariable)
                                {
                                    myRasterVar = (IRasterFunctionVariable)raster;
                                }
                                else
                                {
                                    myRasterVar       = new RasterFunctionVariableClass();
                                    myRasterVar.Name  = "InputRaster";
                                    myRasterVar.Value = raster;
                                }
                                #endregion
                            }
                            #endregion
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                string errorMsg = exc.Message;
            }
        }
        /// <summary>
        /// Set the necessary objects required for the form. In this case
        /// the form is given an arguments object in edit mode, or is required 
        /// to create one in create mode. After getting or creating the arguments
        /// object, template mode is checked for and handled. The template mode 
        /// requires all parameters of the arguments object to converted to variables.
        /// </summary>
        /// <param name="objects">Set of objects required for the form.</param>
        public void SetObjects(ESRI.ArcGIS.esriSystem.ISet objects)
        {
            try
            {
                // Recurse through the objects
                objects.Reset();
                for (int i = 0; i < objects.Count; i++)
                {
                    object currObject = objects.Next();
                    // Find the properties to be set.
                    if (currObject is IPropertySet)
                    {
                        IPropertySet uiParameters = (IPropertySet)currObject;
                        object names, values;
                        uiParameters.GetAllProperties(out names, out values);

                        bool disableForm = false;
                        try { disableForm = Convert.ToBoolean(uiParameters.GetProperty("RFxPropPageIsReadOnly")); }
                        catch (Exception) { }

                        if (disableForm)
                            isFormReadOnly = true;
                        else
                            isFormReadOnly = false;

                        // Check if the arguments object exists in the property set.
                        object functionArgument = null;
                        try { functionArgument = uiParameters.GetProperty("RFxArgument"); }
                        catch (Exception) { }
                        // If not, the form is in create mode.
                        if (functionArgument == null)
                        {
                            #region Create Mode
                            // Create a new arguments object.
                            myArgs = new NDVICustomFunctionArguments();
                            // Create a new property and set the arguments object on it.
                            uiParameters.SetProperty("RFxArgument", myArgs);
                            // Check if a default raster is supplied.
                            object defaultRaster = null;
                            try { defaultRaster = uiParameters.GetProperty("RFxDefaultInputRaster"); }
                            catch (Exception) { }
                            if (defaultRaster != null) // If it is, set it to the raster property.
                                myArgs.Raster = defaultRaster;
                            // Check if the form is in template mode.
                            templateMode = (bool)uiParameters.GetProperty("RFxTemplateEditMode");
                            if (templateMode)
                            {
                                // Since we are in create mode already, new variables have to be 
                                // created for each property of the arguments object.
                                #region Create Variables
                                if (defaultRaster != null)
                                {
                                    // If a default raster is supplied and it is a variable,
                                    // there is no need to create one.
                                    if (defaultRaster is IRasterFunctionVariable)
                                        myRasterVar = (IRasterFunctionVariable)defaultRaster;
                                    else
                                    {
                                        // Create variable object for the InputRaster property.
                                        myRasterVar = new RasterFunctionVariableClass();
                                        myRasterVar.Value = defaultRaster;
                                        myRasterVar.Name = "InputRaster";
                                        myRasterVar.IsDataset = true;
                                    }
                                }

                                // Create a variable for the BandIndices property.
                                myBandIndicesVar = new RasterFunctionVariableClass();
                                myBandIndicesVar.Name = "BandIndices";
                                // Use the default value from the arguments object
                                myBandIndicesVar.Value = myArgs.BandIndices;

                                // Set the variables created as properties on the arguments object.
                                IRasterFunctionArguments rasterFunctionArgs =
                                    (IRasterFunctionArguments)myArgs;
                                rasterFunctionArgs.PutValue("Raster", myRasterVar);
                                rasterFunctionArgs.PutValue("BandIndices", myBandIndicesVar);
                                #endregion
                            }
                            #endregion
                        }
                        else
                        {
                            #region  Edit Mode
                            // Get the arguments object from the property set.
                            myArgs = (INDVICustomFunctionArguments)functionArgument;
                            // Check if the form is in template mode.
                            templateMode = (bool)uiParameters.GetProperty("RFxTemplateEditMode");
                            if (templateMode)
                            {
                                #region Edit Template
                                // In template edit mode, the variables from the arguments object
                                // are extracted.
                                IRasterFunctionArguments rasterFunctionArgs =
                                    (IRasterFunctionArguments)myArgs;
                                object raster = rasterFunctionArgs.GetValue("Raster");

                                // Create or Open the Raster variable.
                                if (raster is IRasterFunctionVariable)
                                    myRasterVar = (IRasterFunctionVariable)raster;
                                else
                                {
                                    myRasterVar = new RasterFunctionVariableClass();
                                    myRasterVar.Name = "InputRaster";
                                    myRasterVar.Value = raster;
                                }
                                #endregion
                            }
                            #endregion
                        }
                    }
                }
            }
            catch (Exception exc)
            {
                string errorMsg = exc.Message;
            }
        }
        /// <summary>
        /// Initialize the Raster function using the argument object. This is one of the two
        /// main functions to implement for a custom Raster function. The raster object is
        /// dereferenced if required and given to the RasterFuntionHelper object to bind.
        /// </summary>
        /// <param name="pArguments">Arguments object used for initialization</param>
        public void Bind(object pArguments)
        {
            try
            {
                // Check if the Arguments object is of the correct type.
                INDVICustomFunctionArguments customFunctionArgs = null;
                if (pArguments is INDVICustomFunctionArguments)
                {
                    customFunctionArgs = (INDVICustomFunctionArguments)pArguments;
                    object inputRaster = customFunctionArgs.Raster;
                    if (customFunctionArgs.Raster is IRasterFunctionVariable)
                    {
                        IRasterFunctionVariable rasterFunctionVariable =
                            (IRasterFunctionVariable)customFunctionArgs.Raster;
                        inputRaster = rasterFunctionVariable.Value;
                    }

                    // Call the Bind method of the Raster Function Helper object.
                    myFunctionHelper.Bind(inputRaster);
                }
                else
                {
                    // Throw an error if incorrect arguments object is passed.
                    throw new System.Exception(
                              "Incorrect arguments object. Expected: INDVICustomFunctionArguments");
                }

                // Check to see if Band Indices exist.
                if (customFunctionArgs.BandIndices != null && customFunctionArgs.BandIndices != "")
                {
                    myBandIndices = customFunctionArgs.BandIndices.Split(' ');
                }
                else
                {
                    // If not, throw an error.
                    throw new System.Exception(
                              "Incorrect parameters specified. Expected: Valid band indices.");
                }

                // Create a new RasterInfo object and initialize from the FunctionHelper object.
                // A new RasterInfo Object is created because assigning myFunctionHelper.RasterInfo
                // directly creates a reference.
                myRasterInfo                        = new RasterInfo();
                myRasterInfo.BandCount              = myFunctionHelper.RasterInfo.BandCount;
                myRasterInfo.BlockHeight            = myFunctionHelper.RasterInfo.BlockHeight;
                myRasterInfo.BlockWidth             = myFunctionHelper.RasterInfo.BlockWidth;
                myRasterInfo.CellSize               = myFunctionHelper.RasterInfo.CellSize;
                myRasterInfo.Extent                 = myFunctionHelper.RasterInfo.Extent;
                myRasterInfo.FirstPyramidLevel      = myFunctionHelper.RasterInfo.FirstPyramidLevel;
                myRasterInfo.Format                 = myFunctionHelper.RasterInfo.Format;
                myRasterInfo.GeodataXform           = myFunctionHelper.RasterInfo.GeodataXform;
                myRasterInfo.MaximumPyramidLevel    = myFunctionHelper.RasterInfo.MaximumPyramidLevel;
                myRasterInfo.NativeExtent           = myFunctionHelper.RasterInfo.NativeExtent;
                myRasterInfo.NativeSpatialReference = myFunctionHelper.RasterInfo.NativeSpatialReference;
                myRasterInfo.NoData                 = myFunctionHelper.RasterInfo.NoData;
                myRasterInfo.Origin                 = myFunctionHelper.RasterInfo.Origin;
                myRasterInfo.PixelType              = rstPixelType.PT_FLOAT; // Output pixel type should be output of the NDVI.
                myRasterInfo.Resampling             = myFunctionHelper.RasterInfo.Resampling;
                myRasterInfo.SupportBandSelection   = myFunctionHelper.RasterInfo.SupportBandSelection;

                // Store required input properties.
                myInpPixeltype = myRasterInfo.PixelType;
                myInpNumBands  = myRasterInfo.BandCount;

                // Set output pixel properties.
                myRasterInfo.BandCount = 1;
                myPixeltype            = rstPixelType.PT_FLOAT;

                // Perform validation to see if the indices passed are valid.
                if (myInpNumBands < 2 || myBandIndices.Length < 2)
                {
                    // If not, throw an error.
                    throw new System.Exception(
                              "Incorrect parameters specified. Expected: Valid band indices.");
                }
                for (int i = 0; i < myBandIndices.Length; ++i)
                {
                    int currBand = Convert.ToInt16(myBandIndices[i]) - 1;
                    if ((currBand < 0) || (currBand > myInpNumBands))
                    {
                        // If not, throw an error.
                        throw new System.Exception(
                                  "Incorrect parameters specified. Expected: Valid band indices.");
                    }
                }
            }
            catch (Exception exc)
            {
                System.Exception myExc = new System.Exception(
                    "Exception caught in Bind method: " + exc.Message, exc);
                throw myExc;
            }
        }