diff --git a/avro.cabal b/avro.cabal
--- a/avro.cabal
+++ b/avro.cabal
@@ -1,7 +1,7 @@
 cabal-version: 1.12
 
 name:           avro
-version:        0.4.4.2
+version:        0.4.4.3
 synopsis:       Avro serialization support for Haskell
 description:    Avro serialization and deserialization support for Haskell
 category:       Data
@@ -27,10 +27,9 @@
     test/data/unions.avsc
     test/data/enums-object.json
     test/data/namespace-inference.json
+    test/data/null-namespace.json
     test/data/unions-object-a.json
     test/data/unions-object-b.json
-    test/data/deconflict/reader.avsc
-    test/data/deconflict/writer.avsc
     test/data/overlay/composite.avsc
     test/data/overlay/expectation.avsc
     test/data/overlay/primitives.avsc
@@ -135,6 +134,8 @@
       Avro.Deconflict.A.Writer
       Avro.Deconflict.B.Reader
       Avro.Deconflict.B.Writer
+      Avro.Deconflict.C.Reader
+      Avro.Deconflict.C.Writer
       Avro.DeconflictSpec
       Avro.DefaultsSpec
       Avro.EncodeRawSpec
diff --git a/src/Data/Avro/Schema.hs b/src/Data/Avro/Schema.hs
--- a/src/Data/Avro/Schema.hs
+++ b/src/Data/Avro/Schema.hs
@@ -222,7 +222,7 @@
 -- @
 renderFullname :: TypeName -> T.Text
 renderFullname TN { baseName, namespace } =
-  T.intercalate "." namespace <> "." <> baseName
+  T.intercalate "." $ namespace ++ [baseName]
 
 -- | Parses a fullname into a 'TypeName', assuming the string
 -- representation is valid.
@@ -268,7 +268,7 @@
 mkTypeName context name ns
   | isFullName name = parseFullname name
   | otherwise       = case ns of
-      Just ns -> TN name $ T.splitOn "." ns
+      Just ns -> TN name $ filter (/= "") (T.splitOn "." ns)
       Nothing -> TN name $ fromMaybe [] $ namespace <$> context
   where isFullName = isJust . T.find (== '.')
 
diff --git a/test/Avro/Deconflict/A/Reader.hs b/test/Avro/Deconflict/A/Reader.hs
--- a/test/Avro/Deconflict/A/Reader.hs
+++ b/test/Avro/Deconflict/A/Reader.hs
@@ -1,13 +1,32 @@
 {-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes       #-}
 {-# LANGUAGE TemplateHaskell   #-}
-module Avro.Deconflict.A.Reader
-where
 
-import Data.Avro.Deconflict
+module Avro.Deconflict.A.Reader where
+
 import Data.Avro.Deriving
+import Text.RawString.QQ
 
-deriveAvro "test/data/deconflict/reader.avsc"
+deriveAvroFromByteString [r|
+{
+  "type": "record",
+  "name": "Outer",
+  "fields": [
+    { "name": "name", "type": "string" },
+    { "name": "inner", "type": {
+        "type": "record",
+        "name": "Inner",
+        "fields": [
+          { "name": "id", "type": "int" },
+          { "name": "smell", "type": ["null", "string"], "default": null }
+        ]
+      }
+    },
+    { "name": "other", "type": "Inner" }
+  ]
+}
+|]
 
 sampleValue :: Outer
 sampleValue = Outer "Peone" (Inner 3 Nothing) (Inner 5 Nothing)
diff --git a/test/Avro/Deconflict/A/Writer.hs b/test/Avro/Deconflict/A/Writer.hs
--- a/test/Avro/Deconflict/A/Writer.hs
+++ b/test/Avro/Deconflict/A/Writer.hs
@@ -1,13 +1,31 @@
 {-# LANGUAGE DeriveGeneric     #-}
 {-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes       #-}
 {-# LANGUAGE TemplateHaskell   #-}
-module Avro.Deconflict.A.Writer
-where
 
-import Data.Avro.Deconflict
+module Avro.Deconflict.A.Writer where
+
 import Data.Avro.Deriving
+import Text.RawString.QQ
 
-deriveAvro "test/data/deconflict/writer.avsc"
+deriveAvroFromByteString [r|
+{
+  "type": "record",
+  "name": "Outer",
+  "fields": [
+    { "name": "name", "type": "string" },
+    { "name": "inner", "type": {
+        "type": "record",
+        "name": "Inner",
+        "fields": [
+          { "name": "id", "type": "int" }
+        ]
+      }
+    },
+    { "name": "other", "type": "Inner" }
+  ]
+}
+|]
 
 sampleValue :: Outer
 sampleValue = Outer "Peone" (Inner 3) (Inner 5)
diff --git a/test/Avro/Deconflict/C/Reader.hs b/test/Avro/Deconflict/C/Reader.hs
new file mode 100644
--- /dev/null
+++ b/test/Avro/Deconflict/C/Reader.hs
@@ -0,0 +1,51 @@
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE TemplateHaskell   #-}
+
+module Avro.Deconflict.C.Reader where
+
+import Data.Avro.Deriving
+import Text.RawString.QQ
+
+deriveAvroFromByteString [r|
+[
+{
+  "type": "record",
+  "name": "Foo",
+  "namespace": "avro.test",
+  "fields": [
+    { "name": "fieldA",
+      "type": ["null", {
+        "type": "record",
+        "name": "Goo",
+        "fields": [
+          { "name": "fieldB1",
+            "type": {
+              "type": "record",
+              "name": "Moo",
+              "fields": [
+                { "name": "name",     "type": "string"  }
+              ]
+            }
+          },
+          { "name": "fieldB2", "type": "Moo" }
+        ]
+      }]
+    }
+  ]
+}
+]
+|]
+
+sampleValue :: Foo
+sampleValue = Foo
+  { fooFieldA = Just Goo
+    { gooFieldB1  = Moo
+      { mooName   = "X"
+      }
+    , gooFieldB2  = Moo
+      { mooName   = "X"
+      }
+    }
+  }
diff --git a/test/Avro/Deconflict/C/Writer.hs b/test/Avro/Deconflict/C/Writer.hs
new file mode 100644
--- /dev/null
+++ b/test/Avro/Deconflict/C/Writer.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE DeriveGeneric     #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE QuasiQuotes       #-}
+{-# LANGUAGE TemplateHaskell   #-}
+
+module Avro.Deconflict.C.Writer where
+
+import Data.Avro.Deriving
+import Text.RawString.QQ
+
+deriveAvroFromByteString [r|
+[
+{
+  "type": "record",
+  "name": "Foo",
+  "namespace": "avro.test",
+  "fields": [
+    { "name": "fieldA",
+      "type": ["null", {
+        "type": "record",
+        "name": "Goo",
+        "fields": [
+          { "name": "fieldB1",
+            "type": {
+              "type": "record",
+              "name": "Moo",
+              "fields": [
+                { "name": "name",     "type": "string"  },
+                { "name": "fullName", "type": ["null", "string"], "default": null }
+              ]
+            }
+          },
+          { "name": "fieldB2", "type": "Moo" }
+        ]
+      }]
+    }
+  ]
+}
+]
+|]
+
+sampleValue :: Foo
+sampleValue = Foo
+  { fooFieldA = Just Goo
+    { gooFieldB1 = Moo
+      { mooName     = "X"
+      , mooFullName = Nothing
+      }
+    , gooFieldB2 = Moo
+      { mooName     = "X"
+      , mooFullName = Nothing
+      }
+    }
+  }
diff --git a/test/Avro/DeconflictSpec.hs b/test/Avro/DeconflictSpec.hs
--- a/test/Avro/DeconflictSpec.hs
+++ b/test/Avro/DeconflictSpec.hs
@@ -14,6 +14,8 @@
 import qualified Avro.Deconflict.A.Writer         as AW
 import qualified Avro.Deconflict.B.Reader         as BR
 import qualified Avro.Deconflict.B.Writer         as BW
+import qualified Avro.Deconflict.C.Reader         as CR
+import qualified Avro.Deconflict.C.Writer         as CW
 import qualified Data.Avro.Decode                 as A (decodeAvro)
 import qualified Data.Avro.Decode.Lazy            as AL
 import qualified Data.Avro.Decode.Lazy.Deconflict as AL
@@ -76,11 +78,11 @@
       AL.decodeContainer w `shouldBe` [ Right BR.sampleValue ]
 
     it "should deconflict lazy value" $ do
-      let payload = A.encode AW.sampleValue
-      let decodedAvro = AL.decodeAvro AW.schema'Outer payload
-      let deconflicted = AL.deconflict AW.schema'Outer AR.schema'Outer decodedAvro
+      let payload = A.encode BW.sampleValue
+      let decodedAvro = AL.decodeAvro BW.schema'Foo payload
+      let deconflicted = AL.deconflict BW.schema'Foo BR.schema'Foo decodedAvro
 
-      AL.fromLazyAvro deconflicted `shouldBe` Success AR.sampleValue
+      AL.fromLazyAvro deconflicted `shouldBe` Success BR.sampleValue
 
     it "should deconflict strict container" $ do
       w <- A.encodeContainer [[BW.sampleValue]]
@@ -92,3 +94,34 @@
       let Right deconflicted = A.deconflict BW.schema'Foo BR.schema'Foo decodedAvro
 
       A.fromAvro deconflicted `shouldBe` Success BR.sampleValue
+
+  describe "Type C" $ do
+    it "should deconflict complex type" $ do
+      let payload = A.encode CW.sampleValue
+      let decodedAvro = AL.decodeAvro CW.schema'Foo payload
+      let res = AL.deconflict CW.schema'Foo CR.schema'Foo decodedAvro
+
+      AL.fromLazyAvro res `shouldBe` Success CR.sampleValue
+
+    it "should deconflict lazy container" $ do
+      w <- liftIO $ A.encodeContainer [[ CW.sampleValue ]]
+      AL.decodeContainer w `shouldBe` [ Right CR.sampleValue ]
+
+    it "should deconflict lazy value" $ do
+      let payload = A.encode CW.sampleValue
+      let decodedAvro = AL.decodeAvro CW.schema'Foo payload
+      let deconflicted = AL.deconflict CW.schema'Foo CR.schema'Foo decodedAvro
+
+      AL.fromLazyAvro deconflicted `shouldBe` Success CR.sampleValue
+
+    it "should deconflict strict container" $ do
+      w <- A.encodeContainer [[CW.sampleValue]]
+      A.decodeContainer w `shouldBe` [[CR.sampleValue]]
+
+    it "should deconflict strict value" $ do
+      let payload = A.encode CW.sampleValue
+      let Right decodedAvro = A.decodeAvro CW.schema'Foo payload
+      let Right deconflicted = A.deconflict CW.schema'Foo CR.schema'Foo decodedAvro
+
+      A.fromAvro deconflicted `shouldBe` Success CR.sampleValue
+
diff --git a/test/Avro/NamespaceSpec.hs b/test/Avro/NamespaceSpec.hs
--- a/test/Avro/NamespaceSpec.hs
+++ b/test/Avro/NamespaceSpec.hs
@@ -28,6 +28,11 @@
     let expectedJSONSchema :: Aeson.Value
         Just expectedJSONSchema = head <$> Aeson.decode schemas
     Aeson.toJSON expected `shouldBe` expectedJSONSchema
+  it "should render names in the null namespace with no leading '.'" $
+    renderFullname (TN "FooType" []) `shouldBe` "FooType"
+  nullNamespaceSchema <- runIO $ getFileName "test/data/null-namespace.json" >>= LBS.readFile
+  it "should generate JSON with null namespaces rendered correctly" $
+    Aeson.decode nullNamespaceSchema `shouldBe` Just expectedNullNamespace
 
 expected :: Schema
 expected = Record
@@ -58,6 +63,18 @@
                       , field "bazzy" $ NamedType "com.example.Bazzy"
                       ]
           }
+
+
+expectedNullNamespace :: Schema
+expectedNullNamespace = Record
+  { name    = "Foo"
+  , aliases = []
+  , doc     = Just "An example schema to test null namespace handling."
+  , order   = Just Ascending
+  , fields  = [field "bar" $ NamedType "Bar", field "baz" $ NamedType "com.example.Baz"]
+  }
+  where field name schema = Field name [] Nothing (Just Ascending) schema Nothing
+
 
 getFileName :: FilePath -> IO FilePath
 getFileName p = do
diff --git a/test/data/deconflict/reader.avsc b/test/data/deconflict/reader.avsc
deleted file mode 100644
--- a/test/data/deconflict/reader.avsc
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "type": "record",
-  "name": "Outer",
-  "fields": [
-    { "name": "name", "type": "string" },
-    { "name": "inner", "type": {
-        "type": "record",
-        "name": "Inner",
-        "fields": [
-          { "name": "id", "type": "int" },
-          { "name": "smell", "type": ["null", "string"], "default": null }
-        ]
-      }
-    },
-    { "name": "other", "type": "Inner" }
-  ]
-}
diff --git a/test/data/deconflict/writer.avsc b/test/data/deconflict/writer.avsc
deleted file mode 100644
--- a/test/data/deconflict/writer.avsc
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "type": "record",
-  "name": "Outer",
-  "fields": [
-    { "name": "name", "type": "string" },
-    { "name": "inner", "type": {
-        "type": "record",
-        "name": "Inner",
-        "fields": [
-          { "name": "id", "type": "int" }
-        ]
-      }
-    },
-    { "name": "other", "type": "Inner" }
-  ]
-}
diff --git a/test/data/null-namespace.json b/test/data/null-namespace.json
new file mode 100644
--- /dev/null
+++ b/test/data/null-namespace.json
@@ -0,0 +1,17 @@
+{
+  "type" : "record",
+  "name" : "Foo",
+  "namespace" : "",
+  "aliases" : [],
+  "doc": "An example schema to test null namespace handling.",
+  "fields" : [
+    {
+      "name" : "bar",
+      "type" : "Bar"
+    },
+    {
+      "name" : "baz",
+      "type" : "com.example.Baz"
+    }
+  ]
+}
