protected override FileDescriptor[] GetFiles(string siteId, bool isTemplate, string relativePath, string[] fileExts)
        {
            FaultContract Fault = null;
            string physicalPath = FileUtils.GetPhysicalPathForId(siteId, isTemplate, relativePath, out Fault);
            if (Fault != null)
                throw new Exception(Fault.Message);

            if (!System.IO.Directory.Exists((physicalPath)))
                throw new Exception("Unable to find files");

            List<FileDescriptor> allFiles = new List<FileDescriptor>();
            string[] dirs = FileExplorerUtility.GetDirectories(physicalPath);
            if (dirs != null && dirs.Length > 0)
            {
                foreach (string dir in dirs)
                {
                    if (string.IsNullOrEmpty(dir))
                        continue;
                    FileDescriptor fileInfo = new FileDescriptor();
                    string fileName = dir;
                    int pos = fileName.LastIndexOf('\\');
                    if (pos > -1)
                        fileName = fileName.Substring(pos + 1);
                    fileInfo.FileName = fileName;
                    fileInfo.IsFolder = true;
                    if (!string.IsNullOrEmpty(relativePath))
                        fileInfo.RelativePath = string.Format("{0}/{1}", relativePath, fileName);
                    else
                        fileInfo.RelativePath = fileName;
                    allFiles.Add(fileInfo);
                }
            }

            string[] files = FileExplorerUtility.GetFiles(physicalPath, fileExts);
            if (files != null && files.Length > 0)
            {
                foreach (string file in files)
                {
                    FileDescriptor fileInfo = new FileDescriptor();
                    string fileName = file;
                    int pos = fileName.LastIndexOf('\\');
                    if (pos > -1)
                        fileName = fileName.Substring(pos + 1);
                    fileInfo.FileName = fileName;

                    if (!string.IsNullOrEmpty(relativePath))
                        fileInfo.RelativePath = string.Format("{0}/{1}", relativePath, fileName);
                    else
                        fileInfo.RelativePath = fileName;
                    allFiles.Add(fileInfo);
                }
            }

            return allFiles.ToArray();
        }
        void onGetFilesCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Cancelled || GetFilesCompleted == null)
                return;

            Exception error = e.Error;
            if (error == null)
                error = GetErrorIfAny(e.Result);
            
            ObservableCollection<FileDescriptor> files = new ObservableCollection<FileDescriptor>();
            if (error == null)
            {
                try
                {
                    XDocument xDoc = XDocument.Parse(e.Result);
                    XElement rootElem = xDoc.Root;
                    if (rootElem != null)
                    {
                        IEnumerable<XElement> fileElems = rootElem.Elements("FileDescriptor");
                        if (fileElems != null)
                        {
                            foreach (XElement fileElem in fileElems)
                            {
                                FileDescriptor file = new FileDescriptor()
                                {
                                    DisplayName = fileElem.Element("DisplayName") != null ? fileElem.Element("DisplayName").Value : null,
                                    FileName = fileElem.Element("FileName") != null ? fileElem.Element("FileName").Value : null,
                                    IsFolder = fileElem.Element("IsFolder") != null ? bool.Parse(fileElem.Element("IsFolder").Value) : false,
                                    RelativePath = fileElem.Element("RelativePath") != null ? fileElem.Element("RelativePath").Value : null,
                                };
                                files.Add(file);
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    error = ex;
                }
            }
            GetFilesCompleted(this, new GetFilesCompletedEventArgs() { 
                 Files = files,
                 UserState = e.UserState,
                 Error = error,
            });
        }
        public override FileDescriptor UploadFile(string siteId, bool isTemplate, string relativePath, string fileName, byte[] fileContents)
        {
            FaultContract Fault = null;
            string physicalPath = FileUtils.GetPhysicalPathForId(siteId, isTemplate, relativePath, out Fault);
            if (Fault != null)
                throw new Exception(Fault.Message);

            if (!System.IO.Directory.Exists((physicalPath)))
                throw new Exception("Unable to upload file");

            string filePath = string.Format("{0}\\{1}", physicalPath, fileName);
            FileExplorerUtility.UploadFile(filePath, fileContents, out Fault);
            FileDescriptor newFile = new FileDescriptor();
            newFile.FileName = fileName;
            if (relativePath != null)
                newFile.RelativePath = string.Format("{0}/{1}", relativePath, fileName);
            else
                newFile.RelativePath = fileName;
            return newFile;
        }
        public void UploadFileToSiteAsync(string siteId, bool isTemplate, string relativePath, string fileName, byte[] fileContents, string fileContentType, object userState = null)
        {            
            Uri uri = CreateRestRequest("Files/Upload", string.Format("siteId={0}&isTemplate={1}&relativePath={2}&filename={3}", siteId, isTemplate, relativePath, fileName));
            HttpWebRequest req = (HttpWebRequest)System.Net.WebRequest.Create(uri);
            req.Method = "POST";
            req.BeginGetRequestStream(new AsyncCallback(delegate(IAsyncResult asynchronousResult)
            {
                HttpWebRequest request = (HttpWebRequest)asynchronousResult.AsyncState;
                using (Stream postStream = request.EndGetRequestStream(asynchronousResult))
                {                    
                    try
                    {
                        postStream.Write(fileContents, 0, fileContents.Length);
                        postStream.Flush();
                        postStream.Close();
                    }
                    catch (Exception err)
                    {
                        postStream.Close();
                        if (UploadFileToSiteCompleted != null)
                            UploadFileToSiteCompleted(this, new UploadFileToSiteCompletedEventArgs() { UserState = userState, Error = err });
                        return;
                    }
                }
                request.BeginGetResponse(new AsyncCallback(delegate(IAsyncResult asynchronousResult2)
                {
                    HttpWebRequest req2 = (HttpWebRequest)asynchronousResult2.AsyncState;
                    HttpWebResponse resp = null;
                    try
                    {
                        resp = (HttpWebResponse)req2.EndGetResponse(asynchronousResult2);
                    }
                    catch (System.Exception err)
                    {
                        if (UploadFileToSiteCompleted != null)
                            UploadFileToSiteCompleted(this, new UploadFileToSiteCompletedEventArgs() { UserState = userState, Error = err });
                        return;
                    }

                    string response = null;
                    Stream streamResponse = resp.GetResponseStream();
                    using (StreamReader streamRead = new StreamReader(streamResponse))
                    {
                        response = streamRead.ReadToEnd();
                    }                    

                    if (UploadFileToSiteCompleted != null)
                    {
                        FileDescriptor file = null;
                        Exception error = GetErrorIfAny(response);
                        if (error == null)
                        {
                            XDocument xDoc = XDocument.Parse(response);
                            XElement fileElem = xDoc.Root;
                            file = new FileDescriptor()
                            {
                                DisplayName = fileElem.Element("DisplayName") != null ? fileElem.Element("DisplayName").Value : null,
                                FileName = fileElem.Element("FileName") != null ? fileElem.Element("FileName").Value : null,
                                IsFolder = fileElem.Element("IsFolder") != null ? bool.Parse(fileElem.Element("IsFolder").Value) : false,
                                RelativePath = fileElem.Element("RelativePath") != null ? fileElem.Element("RelativePath").Value : null,
                            };
                        }

                        Deployment.Current.Dispatcher.BeginInvoke(() =>
                        {
                            UploadFileToSiteCompleted(this, new UploadFileToSiteCompletedEventArgs()
                            {
                                File = file,
                                UserState = userState,
                                Error = error,
                            });
                        });
                    }
                }), request);
            }), req); 
        }