static public List<SalesforceFileProxy> UnzipPackageFilesRecursive(byte[] zip)
        {
            List<SalesforceFileProxy> sffp = new List<SalesforceFileProxy>();
            foreach (ZipEntry zipEntry in ZipFile.Read((Stream)new MemoryStream(zip)))
            {
                byte[] numArray = new byte[zipEntry.UncompressedSize];
                zipEntry.OpenReader().Read(numArray, 0, numArray.Length);
                SalesforceFileProxy projectFileEntity = new SalesforceFileProxy()
                {
                    BinaryBody = numArray,
                    FileBody = Encoding.UTF8.GetString(numArray),
                    FileName = zipEntry.FileName
                };
                sffp.Add(projectFileEntity);

                if (IsZipFile(numArray))
                {
                    List<SalesforceFileProxy> zipList = UnzipStaticResource(numArray, zipEntry.FileName.RemoveExtension());
                    if (zipList.Count > 0)
                    {
                        projectFileEntity.Type = "StaticResourceZip";
                        zipList.AddRange(zipList);
                    }
                    sffp.AddRange(zipList);
                }
            }
            return sffp;
        }
        public static List<SalesforceFileProxy> DownloadAllFilesSynchronously(PackageEntity package, SalesforceContext ctx,  CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (!ctx.IsLoggedIn)
                throw new InvalidOperationException("Service should be logged into Salesforce");

            List<SalesforceFileProxy> listFileProxies = new List<SalesforceFileProxy>();
            RetrieveRequest[] retrieveRequestArray = ConvertPackageToRequests(package);

            List<AsyncResult> listResults = new List<AsyncResult>();

            foreach (var retrieveRequest in retrieveRequestArray)
            {
                RetrieveRequest request = retrieveRequest;
                cancellationToken.ThrowIfCancellationRequested();
                AsyncResult asyncResult = ctx.SessionExpirationWrapper(() => ctx.MetadataServiceAdapter.Retrieve(request));
                listResults.Add(asyncResult);
            }

            cancellationToken.ThrowIfCancellationRequested();
            ICollection<Task<RetrieveResult>> collection = new Collection<Task<RetrieveResult>>();
            foreach (var asyncResult in listResults)
            {
                cancellationToken.ThrowIfCancellationRequested();
                Task<RetrieveResult> task = Task<RetrieveResult>.Factory.StartNew(() => ctx.PollingResult.PollForResultWrapper(3, 180, 3, () =>
                        ctx.CheckRetrieveResult(asyncResult.id), res => res != null, cancellationToken), cancellationToken);
                collection.Add(task);
            }

            ctx.WaitAllTaskskWithHandlingAggregateException(collection.ToArray(), cancellationToken);
            foreach (Task<RetrieveResult> task in collection)
            {
                cancellationToken.ThrowIfCancellationRequested();
                RetrieveResult result = task.Result;

                string fileName = String.Format("{0}\\{1}.zip", ctx.OutputLocation, Guid.NewGuid().ToString());

                bool rawZip = Boolean.Parse(ConfigurationManager.AppSettings["salesforcemigrations:dumprawzip"]);

                if(rawZip)
                {
                    var rawZipFile = new SalesforceFileProxy
                    {
                        FullName = result.id,
                        FileName = String.Format("unpackaged/zips/{0}.zip", result.id),
                        Type = "zip",
                        BinaryBody = result.zipFile
                    };

                    listFileProxies.Add(rawZipFile);
                }
               
                List<SalesforceFileProxy> files = UnzipPackageFilesHelper.UnzipPackageFilesRecursive(result.zipFile);

                UpdateFileProperties(files, result.fileProperties);
                listFileProxies.AddRange(files);
            }
            return listFileProxies;
        }
 public OperationResult CreateNewSalesForceFile(SalesforceFileProxy entity)
 {
     throw new NotImplementedException();
 }
        //private string CreateMetadataContainer()
        //{
        //    return SessionExpirationWrapper(() => _toolingServiceAdapter.Create(new sObject[1]
        //    {
        //        (sObject) new MetadataContainer()
        //        {
        //            Name = Guid.NewGuid().ToString().Substring(0, 32)
        //        }
        //    }))[0].id;
        //}

        //public ContainerAsyncRequest[] CompileApexMetadataContainer(string metadataContainerId, bool noDeploy, string classMemberId = null, IIncrementalSleepPolicy sleepPolicy = null)
        //{
        //    if (sleepPolicy == null)
        //        sleepPolicy = new FixedSleepPolicy();

        //    ContainerAsyncRequest[] compileRequest = { new ContainerAsyncRequest()
        //    {
        //        MetadataContainerId = metadataContainerId,
        //        MetadataContainerMemberId = classMemberId,
        //        IsCheckOnly = noDeploy,
        //        IsCheckOnlySpecified = true
        //    }};

        //    SaveResult[] createCompileResult = SessionExpirationWrapper(() => _toolingServiceAdapter.Create(new sObject[] {compileRequest[0]}));

        //    ContainerAsyncRequest[] containerAsyncRequestArray = TimeoutRunner.RunUntil(() => Compile(createCompileResult), x => x[0].State != "Queued", sleepPolicy, "compiling");
        //    if (containerAsyncRequestArray != null)
        //        return containerAsyncRequestArray;

        //    compileRequest[0] = new ContainerAsyncRequest()
        //    {
        //        MetadataContainerId = metadataContainerId,
        //        MetadataContainerMemberId = classMemberId,
        //        State = "Aborted"
        //    };

        //    SessionExpirationWrapper(() => _toolingServiceAdapter.Create(new sObject[1]
        //    {
        //        compileRequest[0]
        //    }));

        //    throw new BuildAbortedTimeoutException("Time of the request to Salesforce expired. Build aborted.");
        //}

        //private ContainerAsyncRequest[] Compile(SaveResult[] createCompileResult)
        //{
        //    return SessionExpirationWrapper(() => _toolingServiceAdapter.Retrieve("Id, ErrorMsg, CompilerErrors, State", "ContainerAsyncRequest", new string[1]
        //    {
        //        createCompileResult[0].id
        //    }).OfType<ContainerAsyncRequest>().ToArray());
        //}

        //public OperationResult BuildFiles(IEnumerable<ICompilableItem> changedFiles)
        //{
        //    OperationResult operationResult = new OperationResult();
        //    string metadataContainer = this.CreateMetadataContainer();
        //    List<sObject> objects = new List<sObject>();
        //    var compilableItems = changedFiles as IList<ICompilableItem> ?? changedFiles.ToList();

        //    objects.AddRange(GetApexMembers<ApexClassMember>(compilableItems, metadataContainer));
        //    objects.AddRange(GetApexMembers<ApexComponentMember>(compilableItems, metadataContainer));
        //    objects.AddRange(GetApexMembers<ApexTriggerMember>(compilableItems, metadataContainer));
        //    objects.AddRange(GetApexMembers<ApexPageMember>(compilableItems, metadataContainer));

          
        //    List<SaveResult> saveList = new List<SaveResult>();
        //    if (objects.Count > 0)
        //    {
        //        saveList.AddRange(SessionExpirationWrapper(() => _toolingServiceAdapter.Create(objects.ToArray())));
        //    }

        //    if (saveList.Any(o => o.errors != null))
        //    {
        //        foreach (var saveResult in saveList)
        //        {
        //            if (saveResult.errors != null)
        //            {
        //                List<ErrorDescriptor> errorList = saveResult.errors.Select(e => new ErrorDescriptor()
        //                    {
        //                        Id = e.statusCode.ToString(),
        //                        Name = e.message,
        //                        Problem = e.fields == null ? string.Empty : string.Join(";", e.fields)
        //                    }).ToList();
        //                operationResult.Errors.AddRange(errorList);
        //            }
                    
        //        }
        //    }

        //    ContainerAsyncRequest[] containerAsyncRequestArray = CompileApexMetadataContainer(metadataContainer, false, null);

        //    if (containerAsyncRequestArray.Any(o => o.DeployDetails.componentFailures.Any()))
        //    {
        //        operationResult.Errors.AddRange(containerAsyncRequestArray.SelectMany(sm => sm.DeployDetails.componentFailures)
        //                                                    .Select(s => new ErrorDescriptor
        //                                                    {
        //                                                        Name = s.fullName,
        //                                                        Id = s.id,
        //                                                        Line = s.lineNumber.ToString(),
        //                                                        Problem = s.problem,
        //                                                        ProblemType = s.problemType
        //                                                    }));
        //    }
                
        //    return operationResult;
        //}

        private static SalesforceFileProxy FileFactory(dynamic sforceObject, string type)
        {
            SalesforceFileProxy salesFileEntity = new SalesforceFileProxy
            {
                CreatedByName = sforceObject.CreatedById,
                Id = sforceObject.Id,
                NamespacePrefix = sforceObject.NamespacePrefix,
                Type = type
            };


            if (sforceObject.CreatedDate != null)
                salesFileEntity.CreatedDateUtcTicks = sforceObject.CreatedDate.ToFileTimeUtc().ToString();
            
            if (sforceObject.LastModifiedDate != null)
                salesFileEntity.LastModifiedDateUtcTicks = sforceObject.LastModifiedDate.ToFileTimeUtc().ToString();

            try
            {
                if (DynamicExtensions.IsPropertyExist(sforceObject, "Body"))
                    salesFileEntity.FileBody = sforceObject.Body;

                if (DynamicExtensions.IsPropertyExist(sforceObject, "Name"))
                    salesFileEntity.FileName = sforceObject.Name;
            }
            catch
            {
                // ignored
            }
            return salesFileEntity;
        }
        public static List <SalesforceFileProxy> DownloadAllFilesSynchronously(PackageEntity package, SalesforceContext ctx, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            if (!ctx.IsLoggedIn)
            {
                throw new InvalidOperationException("Service should be logged into Salesforce");
            }

            List <SalesforceFileProxy> listFileProxies = new List <SalesforceFileProxy>();

            RetrieveRequest[] retrieveRequestArray = ConvertPackageToRequests(package);

            List <AsyncResult> listResults = new List <AsyncResult>();

            foreach (var retrieveRequest in retrieveRequestArray)
            {
                RetrieveRequest request = retrieveRequest;
                cancellationToken.ThrowIfCancellationRequested();
                AsyncResult asyncResult = ctx.SessionExpirationWrapper(() => ctx.MetadataServiceAdapter.Retrieve(request));
                listResults.Add(asyncResult);
            }

            cancellationToken.ThrowIfCancellationRequested();
            ICollection <Task <RetrieveResult> > collection = new Collection <Task <RetrieveResult> >();

            foreach (var asyncResult in listResults)
            {
                cancellationToken.ThrowIfCancellationRequested();
                Task <RetrieveResult> task = Task <RetrieveResult> .Factory.StartNew(() => ctx.PollingResult.PollForResultWrapper(3, 180, 3, () =>
                                                                                                                                  ctx.CheckRetrieveResult(asyncResult.id), res => res != null, cancellationToken), cancellationToken);

                collection.Add(task);
            }

            ctx.WaitAllTaskskWithHandlingAggregateException(collection.ToArray(), cancellationToken);
            foreach (Task <RetrieveResult> task in collection)
            {
                cancellationToken.ThrowIfCancellationRequested();
                RetrieveResult result = task.Result;

                string fileName = String.Format("{0}\\{1}.zip", ctx.OutputLocation, Guid.NewGuid().ToString());

                bool rawZip = Boolean.Parse(ConfigurationManager.AppSettings["salesforcemigrations:dumprawzip"]);

                if (rawZip)
                {
                    var rawZipFile = new SalesforceFileProxy
                    {
                        FullName   = result.id,
                        FileName   = String.Format("unpackaged/zips/{0}.zip", result.id),
                        Type       = "zip",
                        BinaryBody = result.zipFile
                    };

                    listFileProxies.Add(rawZipFile);
                }

                List <SalesforceFileProxy> files = UnzipPackageFilesHelper.UnzipPackageFilesRecursive(result.zipFile);

                UpdateFileProperties(files, result.fileProperties);
                listFileProxies.AddRange(files);
            }
            return(listFileProxies);
        }
 static public List<SalesforceFileProxy> UnzipPackageFiles(byte[] zip)
 {
     List<SalesforceFileProxy> list = new List<SalesforceFileProxy>();
     foreach (ZipEntry zipEntry in ZipFile.Read(new MemoryStream(zip)))
     {
         byte[] numArray = new byte[zipEntry.UncompressedSize];
         zipEntry.OpenReader().Read(numArray, 0, numArray.Length);
         SalesforceFileProxy fileProxy = new SalesforceFileProxy()
         {
             BinaryBody = numArray,
             FileBody = Encoding.UTF8.GetString(numArray),
             FileName = zipEntry.FileName
         };
         list.Add(fileProxy);
     }
     return list;
 }
 static public List<SalesforceFileProxy> UnzipStaticResource(byte[] bytes, string fileName)
 {
     List<SalesforceFileProxy> list = new List<SalesforceFileProxy>();
     ZipFile zipFile = ZipFile.Read((Stream)new MemoryStream(bytes));
     if (zipFile.Count == 0)
         return list;
     foreach (ZipEntry zipEntry in zipFile)
     {
         byte[] buffer = new byte[zipEntry.UncompressedSize];
         if (!zipEntry.IsDirectory)
         {
             zipEntry.OpenReader().Read(buffer, 0, buffer.Length);
             string str = Path.Combine(fileName, zipEntry.FileName).ReplaceUnixDirectorySeparator().ReplaceWebSeparator();
             SalesforceFileProxy projectFileEntity = new SalesforceFileProxy()
             {
                 BinaryBody = buffer,
                 FileName = str,
                 ResourceFileName = fileName,
                 Type = "StaticResourceZipItem",
                 PathInResource = str
             };
             list.Add(projectFileEntity);
         }
     }
     return list;
 }