public async Task TestCreateRecords()
        {
            string domainName = CreateRandomDomainName();

            IDnsService provider = CreateProvider();
            using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TestTimeout(TimeSpan.FromSeconds(60))))
            {
                DnsConfiguration configuration = new DnsConfiguration(
                    new DnsDomainConfiguration(
                        name: domainName,
                        timeToLive: default(TimeSpan?),
                        emailAddress: "admin@" + domainName,
                        comment: "Integration test domain",
                        records: new DnsDomainRecordConfiguration[] { },
                        subdomains: new DnsSubdomainConfiguration[] { }));

                DnsJob<DnsDomains> createResponse = await provider.CreateDomainsAsync(configuration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                IEnumerable<DnsDomain> createdDomains = Enumerable.Empty<DnsDomain>();
                if (createResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(createResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail();
                }
                else
                {
                    Console.WriteLine(JsonConvert.SerializeObject(createResponse.Response, Formatting.Indented));
                    createdDomains = createResponse.Response.Domains;
                }

                DnsDomain[] domains = ListAllDomains(provider, domainName, null, cancellationTokenSource.Token).ToArray();
                Assert.IsNotNull(domains);
                Assert.AreEqual(1, domains.Length);

                foreach (var domain in domains)
                {
                    Console.WriteLine();
                    Console.WriteLine("Domain: {0} ({1})", domain.Name, domain.Id);
                    Console.WriteLine();
                    Console.WriteLine(await JsonConvert.SerializeObjectAsync(domain, Formatting.Indented));
                }

                string originalData = "127.0.0.1";
                string updatedData = "192.168.0.1";
                string originalCommentValue = "Integration test record";
                string updatedCommentValue = "Integration test record 2";
                TimeSpan? originalTimeToLive;
                TimeSpan? updatedTimeToLive = TimeSpan.FromMinutes(12);

                DomainId domainId = createResponse.Response.Domains[0].Id;
                DnsDomainRecordConfiguration[] recordConfigurations =
                    {
                        new DnsDomainRecordConfiguration(
                            type: DnsRecordType.A,
                            name: string.Format("www.{0}", domainName),
                            data: originalData,
                            timeToLive: null,
                            comment: originalCommentValue,
                            priority: null)
                    };
                DnsJob<DnsRecordsList> recordsResponse = await provider.AddRecordsAsync(domainId, recordConfigurations, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                Assert.IsNotNull(recordsResponse.Response);
                Assert.IsNotNull(recordsResponse.Response.Records);
                DnsRecord[] records = recordsResponse.Response.Records.ToArray();
                Assert.AreEqual(recordConfigurations.Length, records.Length);
                originalTimeToLive = records[0].TimeToLive;
                Assert.AreNotEqual(originalTimeToLive, updatedTimeToLive);

                Assert.AreEqual(originalData, records[0].Data);
                Assert.AreEqual(originalTimeToLive, records[0].TimeToLive);
                Assert.AreEqual(originalCommentValue, records[0].Comment);

                foreach (var record in records)
                {
                    Console.WriteLine();
                    Console.WriteLine("Record: {0} ({1})", record.Name, record.Id);
                    Console.WriteLine();
                    Console.WriteLine(await JsonConvert.SerializeObjectAsync(record, Formatting.Indented));
                }

                DnsDomainRecordUpdateConfiguration recordUpdateConfiguration = new DnsDomainRecordUpdateConfiguration(records[0], records[0].Name, comment: updatedCommentValue);
                await provider.UpdateRecordsAsync(domainId, new[] { recordUpdateConfiguration }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                DnsRecord updatedRecord = await provider.ListRecordDetailsAsync(domainId, records[0].Id, cancellationTokenSource.Token);
                Assert.IsNotNull(updatedRecord);
                Assert.AreEqual(originalData, updatedRecord.Data);
                Assert.AreEqual(originalTimeToLive, updatedRecord.TimeToLive);
                Assert.AreEqual(updatedCommentValue, updatedRecord.Comment);

                recordUpdateConfiguration = new DnsDomainRecordUpdateConfiguration(records[0], records[0].Name, timeToLive: updatedTimeToLive);
                await provider.UpdateRecordsAsync(domainId, new[] { recordUpdateConfiguration }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                updatedRecord = await provider.ListRecordDetailsAsync(domainId, records[0].Id, cancellationTokenSource.Token);
                Assert.IsNotNull(updatedRecord);
                Assert.AreEqual(originalData, updatedRecord.Data);
                Assert.AreEqual(updatedTimeToLive, updatedRecord.TimeToLive);
                Assert.AreEqual(updatedCommentValue, updatedRecord.Comment);

                recordUpdateConfiguration = new DnsDomainRecordUpdateConfiguration(records[0], records[0].Name, data: updatedData);
                await provider.UpdateRecordsAsync(domainId, new[] { recordUpdateConfiguration }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                updatedRecord = await provider.ListRecordDetailsAsync(domainId, records[0].Id, cancellationTokenSource.Token);
                Assert.IsNotNull(updatedRecord);
                Assert.AreEqual(updatedData, updatedRecord.Data);
                Assert.AreEqual(updatedTimeToLive, updatedRecord.TimeToLive);
                Assert.AreEqual(updatedCommentValue, updatedRecord.Comment);

                await provider.RemoveRecordsAsync(domainId, new[] { records[0].Id }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);

                DnsJob deleteResponse = await provider.RemoveDomainsAsync(createdDomains.Select(i => i.Id), false, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (deleteResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(deleteResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail("Failed to delete temporary domain created during the integration test.");
                }
            }
        }
        public async Task TestCreateSubdomain()
        {
            string domainName = CreateRandomDomainName();
            string subdomainName = "www";

            IDnsService provider = CreateProvider();
            using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TestTimeout(TimeSpan.FromSeconds(60))))
            {
                DnsConfiguration configuration = new DnsConfiguration(
                    new DnsDomainConfiguration(
                        name: domainName,
                        timeToLive: default(TimeSpan?),
                        emailAddress: "admin@" + domainName,
                        comment: "Integration test domain",
                        records: new DnsDomainRecordConfiguration[] { },
                        subdomains: new DnsSubdomainConfiguration[]
                            {
                                new DnsSubdomainConfiguration(
                                    emailAddress: string.Format("sub-admin@{0}.{1}", subdomainName, domainName),
                                    name: string.Format("{0}.{1}", subdomainName, domainName),
                                    comment: "Integration test subdomain")
                            }));

                DnsJob<DnsDomains> createResponse = await provider.CreateDomainsAsync(configuration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                IEnumerable<DnsDomain> createdDomains = Enumerable.Empty<DnsDomain>();
                if (createResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(createResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail();
                }
                else
                {
                    Console.WriteLine(JsonConvert.SerializeObject(createResponse.Response, Formatting.Indented));
                    createdDomains = createResponse.Response.Domains;
                }

                DnsDomain[] domains = ListAllDomains(provider, domainName, null, cancellationTokenSource.Token).ToArray();
                Assert.IsNotNull(domains);

                if (!domains.Any())
                    Assert.Inconclusive("No domains were returned by the server");

                foreach (var domain in domains)
                {
                    Console.WriteLine();
                    Console.WriteLine("Domain: {0} ({1})", domain.Name, domain.Id);
                    Console.WriteLine();
                    Console.WriteLine(await JsonConvert.SerializeObjectAsync(domain, Formatting.Indented));
                }

                DomainId domainId = createResponse.Response.Domains[0].Id;
                DnsSubdomain[] subdomains = ListAllSubdomains(provider, domainId, null, cancellationTokenSource.Token).ToArray();
                Assert.IsNotNull(subdomains);
                Assert.AreEqual(1, subdomains.Length);
                foreach (var subdomain in subdomains)
                {
                    Console.WriteLine();
                    Console.WriteLine("Subdomain: {0} ({1})", subdomain.Name, subdomain.Id);
                    Console.WriteLine();
                    Console.WriteLine(await JsonConvert.SerializeObjectAsync(subdomain, Formatting.Indented));
                }

                DnsJob deleteResponse = await provider.RemoveDomainsAsync(createdDomains.Select(i => i.Id), true, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (deleteResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(deleteResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail("Failed to delete temporary domain created during the integration test.");
                }
            }
        }
        public async Task TestCloneDomain()
        {
            string domainName = CreateRandomDomainName();
            string clonedName = CreateRandomDomainName();

            IDnsService provider = CreateProvider();
            using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TestTimeout(TimeSpan.FromSeconds(60))))
            {
                List<DomainId> domainsToRemove = new List<DomainId>();

                DnsConfiguration configuration = new DnsConfiguration(
                    new DnsDomainConfiguration(
                        name: domainName,
                        timeToLive: default(TimeSpan?),
                        emailAddress: "admin@" + domainName,
                        comment: "Integration test domain",
                        records: new DnsDomainRecordConfiguration[] { },
                        subdomains: new DnsSubdomainConfiguration[] { }));

                DnsJob<DnsDomains> createResponse = await provider.CreateDomainsAsync(configuration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (createResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(createResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail();
                }
                else
                {
                    Console.WriteLine(JsonConvert.SerializeObject(createResponse.Response, Formatting.Indented));
                    domainsToRemove.AddRange(createResponse.Response.Domains.Select(i => i.Id));
                }

                DnsJob<DnsDomains> cloneResponse = await provider.CloneDomainAsync(createResponse.Response.Domains[0].Id, clonedName, true, true, true, true, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (cloneResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(cloneResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail();
                }
                else
                {
                    Console.WriteLine(JsonConvert.SerializeObject(cloneResponse.Response, Formatting.Indented));
                    domainsToRemove.AddRange(cloneResponse.Response.Domains.Select(i => i.Id));
                }

                DnsJob deleteResponse = await provider.RemoveDomainsAsync(domainsToRemove, false, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (deleteResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(deleteResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail("Failed to delete temporary domain created during the integration test.");
                }
            }
        }
        public async Task TestDomainExportImport()
        {
            string domainName = CreateRandomDomainName();

            IDnsService provider = CreateProvider();
            using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TestTimeout(TimeSpan.FromSeconds(60))))
            {
                List<DomainId> domainsToRemove = new List<DomainId>();

                DnsConfiguration configuration = new DnsConfiguration(
                    new DnsDomainConfiguration(
                        name: domainName,
                        timeToLive: default(TimeSpan?),
                        emailAddress: "admin@" + domainName,
                        comment: "Integration test domain",
                        records: new DnsDomainRecordConfiguration[] { },
                        subdomains: new DnsSubdomainConfiguration[] { }));

                DnsJob<DnsDomains> createResponse = await provider.CreateDomainsAsync(configuration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (createResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(createResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail("Failed to create a test domain.");
                }
                else
                {
                    Console.WriteLine(JsonConvert.SerializeObject(createResponse.Response, Formatting.Indented));
                    domainsToRemove.AddRange(createResponse.Response.Domains.Select(i => i.Id));
                }

                DnsJob<ExportedDomain> exportedDomain = await provider.ExportDomainAsync(createResponse.Response.Domains[0].Id, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (exportedDomain.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(exportedDomain.Error.ToString(Formatting.Indented));
                    Assert.Fail("Failed to export test domain.");
                }

                Assert.AreEqual(DnsJobStatus.Completed, exportedDomain.Status);
                Assert.IsNotNull(exportedDomain.Response);

                Console.WriteLine("Exported domain:");
                Console.WriteLine(JsonConvert.SerializeObject(exportedDomain.Response, Formatting.Indented));
                Console.WriteLine();
                Console.WriteLine("Formatted exported output:");
                Console.WriteLine(exportedDomain.Response.Contents);

                Assert.IsNotNull(exportedDomain.Response.Id);
                Assert.IsFalse(string.IsNullOrEmpty(exportedDomain.Response.AccountId));
                Assert.IsFalse(string.IsNullOrEmpty(exportedDomain.Response.Contents));
                Assert.IsNotNull(exportedDomain.Response.ContentType);

                DnsJob deleteResponse = await provider.RemoveDomainsAsync(domainsToRemove, false, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (deleteResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(deleteResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail("Failed to delete temporary domain created during the integration test.");
                }

                domainsToRemove.Clear();

                SerializedDomain serializedDomain =
                    new SerializedDomain(
                        RemoveDefaultNameserverEntries(exportedDomain.Response.Contents),
                        exportedDomain.Response.ContentType);
                DnsJob<DnsDomains> importedDomain = await provider.ImportDomainAsync(new[] { serializedDomain }, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (importedDomain.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(importedDomain.Error.ToString(Formatting.Indented));
                    Assert.Fail("Failed to import the test domain.");
                }
                else
                {
                    Console.WriteLine(JsonConvert.SerializeObject(importedDomain.Response, Formatting.Indented));
                    domainsToRemove.AddRange(importedDomain.Response.Domains.Select(i => i.Id));
                }

                deleteResponse = await provider.RemoveDomainsAsync(domainsToRemove, false, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (deleteResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(deleteResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail("Failed to delete temporary domain created during the integration test.");
                }
            }
        }
        public async Task TestUpdateDomain()
        {
            string domainName = CreateRandomDomainName();

            IDnsService provider = CreateProvider();
            using (CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(TestTimeout(TimeSpan.FromSeconds(60))))
            {
                DnsConfiguration configuration = new DnsConfiguration(
                    new DnsDomainConfiguration(
                        name: domainName,
                        timeToLive: default(TimeSpan?),
                        emailAddress: "admin@" + domainName,
                        comment: "Integration test domain",
                        records: new DnsDomainRecordConfiguration[] { },
                        subdomains: new DnsSubdomainConfiguration[] { }));

                DnsJob<DnsDomains> createResponse = await provider.CreateDomainsAsync(configuration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                IEnumerable<DnsDomain> createdDomains = Enumerable.Empty<DnsDomain>();
                if (createResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(createResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail();
                }
                else
                {
                    Console.WriteLine(JsonConvert.SerializeObject(createResponse.Response, Formatting.Indented));
                    createdDomains = createResponse.Response.Domains;
                }

                DnsDomain[] domains = ListAllDomains(provider, domainName, null, cancellationTokenSource.Token).ToArray();
                Assert.IsNotNull(domains);

                if (!domains.Any())
                    Assert.Inconclusive("No domains were returned by the server");

                DnsUpdateConfiguration updateConfiguration = new DnsUpdateConfiguration(
                    new DnsDomainUpdateConfiguration(domains[0], comment: "Integration test domain 2"));
                await provider.UpdateDomainsAsync(updateConfiguration, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);

                DnsJob deleteResponse = await provider.RemoveDomainsAsync(createdDomains.Select(i => i.Id), false, AsyncCompletionOption.RequestCompleted, cancellationTokenSource.Token, null);
                if (deleteResponse.Status == DnsJobStatus.Error)
                {
                    Console.WriteLine(deleteResponse.Error.ToString(Formatting.Indented));
                    Assert.Fail("Failed to delete temporary domain created during the integration test.");
                }
            }
        }