@testset "fq_default_embed.embed" begin

  for i in 1:10
    p = ZZRingElem(next_prime(rand(1:999)))

    k1, x1 = finite_field(p, 1, "x1")
    k2, x2 = finite_field(p, 2, "x2")
    k3, x3 = finite_field(p, 3, "x3")
    k4, x4 = finite_field(p, 4, "x4")
    k6, x6 = finite_field(p, 6, "x6")
    k8, x8 = finite_field(p, 8, "x8")
    k9, x9 = finite_field(p, 9, "x9")
    k12, x12 = finite_field(p, 12, "x12")
    k16, x16 = finite_field(p, 16, "x16")
    k18, x18 = finite_field(p, 18, "x18")
    k24, x24 = finite_field(p, 24, "x24")

    S = Set([(k4, k12),
             (k6, k24),
             (k8, k16),
             (k2, k16),
             (k3, k6),
             (k9, k18),
             (k6, k12),
             (k3, k18),
             (k4, k16),
             (k6, k18),
             (k2, k8),
             (k12, k24),
             (k3, k9),
             (k2, k6),
             (k8, k24),
             (k3, k24),
             (k2, k12),
             (k3, k12),
             (k2, k24),
             (k2, k4),
             (k4, k24),
             (k1, k3),
             (k1, k4),
             (k1, k6),
             (k1, k16),
             (k1, k12),
             (k1, k9),
             (k4, k8)])

    f = Dict()
    # Compute embeddings in a random order
    while !isempty(S)
      k, K = pop!(S, rand(S))
      f[(k, K)] = embed(k, K)
    end

    # Check that the embeddings are compatible
    @test f[k6, k18](f[k3, k6](x3)) == f[k3, k18](x3)
    @test f[k8, k16](f[k2, k8](x2)) == f[k2, k16](x2)
    @test f[k12, k24](f[k6, k12](x6)) == f[k6, k24](x6)
    @test f[k9, k18](f[k3, k9](x3)) == f[k3, k18](x3)
    @test f[k6, k24](f[k3, k6](x3)) == f[k3, k24](x3)
    @test f[k6, k12](f[k2, k6](x2)) == f[k2, k12](x2)
    @test f[k6, k12](f[k3, k6](x3)) == f[k3, k12](x3)
    @test f[k12, k24](f[k3, k12](x3)) == f[k3, k24](x3)
    @test f[k6, k24](f[k2, k6](x2)) == f[k2, k24](x2)
    @test f[k12, k24](f[k2, k12](x2)) == f[k2, k24](x2)
    @test f[k12, k24](f[k4, k12](x4)) == f[k4, k24](x4)
    @test f[k4, k12](f[k2, k4](x2)) == f[k2, k12](x2)
    @test f[k4, k24](f[k2, k4](x2)) == f[k2, k24](x2)
    @test f[k8, k16](f[k4, k8](x4)) == f[k4, k16](x4)
    @test f[k8, k24](f[k4, k8](x4)) == f[k4, k24](x4)
    @test f[k4, k8](f[k2, k4](x2)) == f[k2, k8](x2)
    @test f[k4, k16](f[k2, k4](x2)) == f[k2, k16](x2)
    @test f[k4, k16](f[k1, k4](x1)) == f[k1, k16](x1)
    @test f[k3, k9](f[k1, k3](x1)) == f[k1, k9](x1)
    @test f[k6, k12](f[k1, k6](x1)) == f[k1, k12](x1)
  end
end

@testset "fq_default_embed.preimage_map" begin

  for i in 1:10
    p = ZZRingElem(next_prime(rand(1:999)))

    a, b = rand(1:5), rand(1:5)
    ka, xa = finite_field(p, a, "xa")
    kab, xab = finite_field(p, a*b, "xab")

    f = preimage_map(ka, kab)
    g = embed(ka, kab)

    for j in 1:20
      x = rand(ka)
      @test x == @inferred f(g(x))
      @test x == @inferred preimage(g, g(x))
      @test x == @inferred ka(kab(x))
    end
  end
end

@testset "fq_default_embed.transitive_closure" begin

  S = Set(2:997)
  for i in 1:40

    p = rand(S)
    while !is_prime(p)
      p = rand(S)
    end
    pop!(S, p)
    p = ZZRingElem(p)

    F = finite_field(p, 4, "s", cached = false)[1]
    Z = Native.GF(p)
    R, x = polynomial_ring(Z, "x")

    P1 = R(rand(Z, 4)) + x^4
    F1 = factor(P1)
    P2 = R(rand(Z, 4)) + x^4
    F2 = factor(P2)
    P3 = R(rand(Z, 4)) + x^4
    F3 = factor(P3)
    P4 = R(rand(Z, 4)) + x^4
    F4 = factor(P4)

    while length(F1) != 1 || F1[first.(collect(F1))[1]] != 1
      P1 = R(rand(Z, 4)) + x^4
      F1 = factor(P1)
    end

    while length(F2) != 1 || F2[first.(collect(F2))[1]] != 1
      P2 = R(rand(Z, 4)) + x^4
      F2 = factor(P2)
    end

    while length(F3) != 1 || F3[first.(collect(F3))[1]] != 1
      P3 = R(rand(Z, 4)) + x^4
      F3 = factor(P3)
    end

    while length(F4) != 1 || F4[first.(collect(F4))[1]] != 1
      P4 = R(rand(Z, 4)) + x^4
      F4 = factor(P4)
    end

    K1 = FqField(P1, :r1)
    K2 = FqField(P2, :r2)
    K3 = FqField(P3, :r3)
    K4 = FqField(P4, :r4)

    K = Set([K1, K2, K3, K4])
    while !isempty(K)
      embed(pop!(K, rand(K)), F)
    end

    @test length(F.subfields[4]) == 4

    x1 = rand(K1)
    x2 = rand(K2)
    x3 = rand(K3)
    x4 = rand(K4)

    @test F(x1) == F(K2(x1))
    @test F(x2) == F(K3(x2))
    @test K4(x3) == K4(K1(x3))
    @test K1(K2(x4)) == K1(K3(x4))

  end
end
