// GetPhotoStatus allows the Eye-Fi card to query the server as to the current uploaded
        // status of a file. Even more important is that it authenticates the card to the server
        // by the use of the <credential> field. Essentially if the credential is correct the
        // server should allow files with the given filesignature to be uploaded.
        private string GetPhotoStatus(Stream data)
        {
            Utilities.Log("  GetPhotoStatus Begin", false);

            XDocument doc = XDocument.Load(data);
            EyeFiContentHandler contentHandler = new EyeFiContentHandler(doc);

            string credentialString = contentHandler.MacAddress + App.ViewModel.EyeFiUploadKey + App.ViewModel.EyeFiServerInstance.ServerNonce;
            byte[] binaryCredentials = Utilities.HexToBytes(credentialString);
            string credential = MD5Core.GetHashString(binaryCredentials).ToLower();

            if (contentHandler.Credential != credential)
            {
                Utilities.Log("  Authentication Error:" + Environment.NewLine + "    EyeFi Credential: " + contentHandler.Credential + Environment.NewLine + "    App Credential: " + credential, false);
                return "Authentication error";
            }

            doc = EyeFiSOAPMessages.GetPhotoStatusResponseXML(App.ViewModel.EyeFiFileId);

            App.ViewModel.EyeFiFileId++;

            return Utilities.EncodeXml(doc, UTF8Encoding.UTF8);
        }
        // Handles receiving the actual photograph from the card.
        // data will most likely contain multipart binary post data that needs to be parsed
        private string UploadPhoto(IRequest request)
        {
            Utilities.Log("  UploadPhoto Begin", false);

            // Parse the multipart/form-data
            MultiPartDecoder decoder = new MultiPartDecoder();
            DecodedData data = decoder.Decode(request.Body, request.ContentType, request.Encoding);

            // Parse the SOAPENVELOPE using the EyeFiContentHandler()
            XDocument doc = XDocument.Parse(data.Parameters.Get("SOAPENVELOPE").Value);
            EyeFiContentHandler contentHandler = new EyeFiContentHandler(doc);

            // Get the newly uploaded file into memory
            using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                using (IsolatedStorageFileStream untrustedFile = new IsolatedStorageFileStream(data.Files["FILENAME"].TempFileName,FileMode.Open,store))
                {
                    // Integrity check the file before writing it out
                    string verifiedDigest = EyeFiCrypto.CalculateIntegrityDigest(Utilities.StreamToBytes(untrustedFile), App.ViewModel.EyeFiUploadKey);
                    string unverifiedDigest = data.Parameters.Get("INTEGRITYDIGEST").Value;

                    Utilities.Log("  Comparing my digest [" + verifiedDigest + "] to card's digest [" + unverifiedDigest + "].", false);

                    if (verifiedDigest == unverifiedDigest)
                    {
                        TarArchive tarball = TarArchive.Open(untrustedFile);
                        using (IReader reader = tarball.ExtractAllEntries())
                        {
                            while (reader.MoveToNextEntry())
                            {
                                if (!reader.Entry.IsDirectory &! reader.Entry.FilePath.Contains(".log"))
                                {
                                    string imageName = (reader.Entry.FilePath).Substring(0, reader.Entry.FilePath.IndexOf('.') + 4);
                                    string imagePath = Path.Combine(App.ViewModel.DownloadLocation, imageName);

                                    Utilities.Log("  Extracting image to " + imagePath, false);

                                    using (IsolatedStorageFileStream image = new IsolatedStorageFileStream(imagePath, FileMode.Create, store))
                                    {
                                        reader.WriteEntryTo(image);
                                    }

                                    NotifyPictureReceived(imagePath);
                                }
                            }
                        }
                        doc = EyeFiSOAPMessages.GetUploadPhotoResponseXML("true");
                        return Utilities.EncodeXml(doc, UTF8Encoding.UTF8);
                    }
                    else
                    {
                        doc = EyeFiSOAPMessages.GetUploadPhotoResponseXML("false");
                        return Utilities.EncodeXml(doc, UTF8Encoding.UTF8);
                    }
                }
            }
        }
        private string StartSession(Stream data)
        {
            Utilities.Log("  StartSession Begin", false);

            XDocument doc = XDocument.Load(data);
            EyeFiContentHandler contentHandler = new EyeFiContentHandler(doc);

            string credentialString = contentHandler.MacAddress + contentHandler.Cnonce + App.ViewModel.EyeFiUploadKey;
            byte[] binaryCredentials = Utilities.HexToBytes(credentialString);
            string credential = MD5Core.GetHashString(binaryCredentials).ToLower();

            doc = EyeFiSOAPMessages.GetStartSessionResponseXML(credential, App.ViewModel.EyeFiServerInstance.ServerNonce, contentHandler.TransferMode, contentHandler.TransferModeTimeStamp);
            return Utilities.EncodeXml(doc, UTF8Encoding.UTF8);
        }