/// <include file='doc\VsCheckoutService.uex' path='docs/doc[@for="VsCheckoutService.CheckoutFile2"]/*' />
        /// <devdoc>
        ///     Checks out the given file, if possible. If the file is already checked out, or
        ///     does not need to be checked out, no Exception is thrown and the function returns.
        ///     This also checks out any additional buffers passed in through the additionalBuffers
        ///     parameter.
        ///     If the file needs be be checked out ot be edited, and it cannot be checked out,
        ///     an exception is thrown.
        ///
        /// </devdoc>
        public virtual void CheckoutFile(string fileName, string[] additionalBuffers)
        {
            EnsureTextManager();
            if (disable)
            {
                return;
            }

            Debug.Assert(textManagerService != null, "Couldn't get text manager service!");
            if (fileName == null)
            {
                throw new ArgumentException(SR.GetString(SR.InvalidArgument, "fileName", "null"));
            }
            if ((!DoesFileNeedCheckout(fileName)) && (additionalBuffers == null || additionalBuffers.Length == 0))
            {
                return;
            }
            bool userCanceled = false;
            bool pSuccess     = false;
            int  errorCode    = 0;

            try{
                IVsQueryEditQuerySave2 qeqs = (IVsQueryEditQuerySave2)serviceProvider.GetService(typeof(SVsQueryEditQuerySave2));

                if (qeqs != null)
                {
                    _VSQueryEditResult editVerdict;

                    string [] files = GetFilesFromHierarchy(fileName, additionalBuffers);
                    if (files.Length == 0)
                    {
                        return;
                    }
                    IntPtr fileMemory = GetWStrArray(files);
                    try {
                        _VSQueryEditResultFlags result = qeqs.QueryEditFiles(0, files.Length, fileMemory, new int[files.Length], 0, out editVerdict);
                        pSuccess = editVerdict == _VSQueryEditResult.QER_EditOK;
                        if (!pSuccess &&
                            ((int)result & (int)_VSQueryEditResultFlags.QER_CheckoutCanceledOrFailed) != 0)
                        {
                            userCanceled = true;
                        }
                    }
                    finally {
                        FreeWStrArray(fileMemory, files.Length);
                    }
                }
                else
                {
                    int result = textManagerService.AttemptToCheckOutBufferFromScc2(fileName, ref pSuccess);
                    if (!pSuccess &&
                        (result & (int)_VSQueryEditResultFlags.QER_CheckoutCanceledOrFailed) != 0)
                    {
                        userCanceled = true;
                    }
                }
            } catch (ExternalException ex) {
                errorCode = ex.ErrorCode;
            }

            if (!pSuccess)
            {
                if (!userCanceled)
                {
                    throw new CheckoutException(SR.GetString(SR.CHECKOUTSERVICEUnableToCheckout), errorCode);
                }
                else
                {
                    throw CheckoutException.Canceled;
                }
            }

            // You can actually configure SSC to edit a read only file, so do not fail the checkout if
            // the file is read only.
            //

            /*
             * if (IsFileReadOnly(fileName)){
             *  Debug.Fail("Checkout returned success, but file is still readonly.  SCC failed to correctly checkout the file.");
             *  throw CheckoutException.Canceled;
             * }
             */
        }