diff --git a/README.md b/README.md
index 9b3b2cc..55e9369 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 [![Built with Crystal](https://img.shields.io/badge/built%20with-crystal-000000.svg?style=flat-square)](https://crystal-lang.org/)
 [![Build Status](https://travis-ci.org/Blacksmoke16/oq.svg?branch=master)](https://travis-ci.org/Blacksmoke16/oq)
 [![Latest release](https://img.shields.io/github/release/Blacksmoke16/oq.svg?style=flat-square)](https://github.com/Blacksmoke16/oq/releases)
-[![Snap Status](https://build.snapcraft.io/badge/Blacksmoke16/oq.svg)](https://build.snapcraft.io/user/Blacksmoke16/oq)
+[![oq](https://snapcraft.io/omni-q/badge.svg)](https://snapcraft.io/omni-q)
 
 A performant, portable `jq` wrapper thats facilitates the consumption and output of formats other than JSON; using `jq` filters to transform the data.
 
@@ -33,7 +33,7 @@ Usage: oq [--help] [oq-arguments] [jq-arguments] jq_filter [file [files...]]
     --help                          Show this help message.
     -i FORMAT, --input FORMAT       Format of the input data. Supported formats: json, yaml, xml.
     -o FORMAT, --output FORMAT      Format of the output data. Supported formats: json, yaml, xml.
-    --xml-root=ROOT                 Name of the root XML element if converting to XML.
+    --xml-root ROOT                 Name of the root XML element if converting to XML.
 ```
 
 ## Roadmap
diff --git a/shard.yml b/shard.yml
index 9bf37b6..87e8cbc 100644
--- a/shard.yml
+++ b/shard.yml
@@ -1,4 +1,4 @@
-name: omni-q
+name: oq
 
 description: |
   A performant, and portable jq wrapper thats facilitates the consumption and output of formats other than JSON; using jq filters to transform the data.
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index cc4393c..6226ec7 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -4,7 +4,7 @@ summary: A performant, and portable jq wrapper to support formats other than JSO
 description: |
   A performant, and portable jq wrapper thats facilitates the consumption and output of formats other than JSON; using jq filters to transform the data.
 
-grade: devel
+grade: stable
 confinement: strict
 base: core18
 
diff --git a/spec/oq_spec.cr b/spec/oq_spec.cr
index 73f4386..4154a88 100644
--- a/spec/oq_spec.cr
+++ b/spec/oq_spec.cr
@@ -12,23 +12,23 @@ JSON
 
 describe Oq do
   describe "when given a filter file" do
-    it "returns the correct output" do
+    it "should return the correct output" do
       run_binary(input: SIMPLE_JSON_OBJECT, args: ["-f", "spec/assets/test_filter"]) do |output|
-        output.should eq "\"Jim\"\n"
+        output.should eq %("Jim"\n)
       end
     end
   end
 
   describe "with a simple filter" do
-    it "returns the correct output" do
+    it "should return the correct output" do
       run_binary(input: SIMPLE_JSON_OBJECT, args: [".name"]) do |output|
-        output.should eq "\"Jim\"\n"
+        output.should eq %("Jim"\n)
       end
     end
   end
 
   describe "with a filter to get nested values" do
-    it "returns the correct output" do
+    it "should return the correct output" do
       run_binary(input: NESTED_JSON_OBJECT, args: [".foo.bar.baz"]) do |output|
         output.should eq "5\n"
       end
@@ -36,8 +36,8 @@ describe Oq do
   end
 
   describe "with a filter to get nested values and YAML input" do
-    it "returns the correct output" do
-      run_binary(input: "---\nfoo:\n  bar:\n    baz: 5", args: [".foo.bar.baz", "-i", "yaml"]) do |output|
+    it "should return the correct output" do
+      run_binary(input: "---\nfoo:\n  bar:\n    baz: 5", args: ["-i", "yaml", ".foo.bar.baz"]) do |output|
         output.should eq "5\n"
       end
     end
@@ -45,7 +45,7 @@ describe Oq do
 
   describe "with YAML output" do
     it "should return the correct output" do
-      run_binary(input: NESTED_JSON_OBJECT, args: [".", "-o", "yaml"]) do |output|
+      run_binary(input: NESTED_JSON_OBJECT, args: ["-o", "yaml", "."]) do |output|
         output.should eq "---\nfoo:\n  bar:\n    baz: 5\n"
       end
     end
@@ -53,7 +53,7 @@ describe Oq do
 
   describe "with XML output" do
     it "should return the correct output" do
-      run_binary(input: NESTED_JSON_OBJECT, args: [".", "-o", "xml"]) do |output|
+      run_binary(input: NESTED_JSON_OBJECT, args: ["-o", "xml", "."]) do |output|
         output.should eq "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n  <foo>\n    <bar>\n      <baz>5</baz>\n    </bar>\n  </foo>\n</root>\n"
       end
     end
@@ -61,7 +61,7 @@ describe Oq do
 
   describe "with YAML input" do
     it "should return the correct output" do
-      run_binary(input: "---\nfoo:\n  bar:\n    baz: 5\n", args: [".", "-c", "-i", "yaml"]) do |output|
+      run_binary(input: "---\nfoo:\n  bar:\n    baz: 5\n", args: ["-c", "-i", "yaml", "."]) do |output|
         output.should eq "#{NESTED_JSON_OBJECT}\n"
       end
     end
@@ -77,7 +77,7 @@ describe Oq do
 
   describe "with multiple JSON file input" do
     it "should return the correct output" do
-      run_binary(input: "", args: [".", "-c", "spec/assets/data1.json", "spec/assets/data2.json"]) do |output|
+      run_binary(input: "", args: ["-c", ".", "spec/assets/data1.json", "spec/assets/data2.json"]) do |output|
         output.should eq %({"name":"Jim"}\n{"name":"Bob"}\n)
       end
     end
@@ -85,7 +85,7 @@ describe Oq do
 
   describe "with multiple JSON file input and slurp" do
     it "should return the correct output" do
-      run_binary(input: "", args: [".", "-c", "--slurp", "spec/assets/data1.json", "spec/assets/data2.json"]) do |output|
+      run_binary(input: "", args: ["-c", "--slurp", ".", "spec/assets/data1.json", "spec/assets/data2.json"]) do |output|
         output.should eq %([{"name":"Jim"},{"name":"Bob"}]\n)
       end
     end
@@ -93,7 +93,7 @@ describe Oq do
 
   describe "with multiple YAML file input" do
     it "should return the correct output" do
-      run_binary(input: "", args: [".", "-c", "-i", "yaml", "spec/assets/data1.yml", "spec/assets/data2.yml"]) do |output|
+      run_binary(input: "", args: ["-c", "-i", "yaml", ".", "spec/assets/data1.yml", "spec/assets/data2.yml"]) do |output|
         output.should eq %({"name":"Jim"}\n{"age":17}\n)
       end
     end
@@ -101,7 +101,7 @@ describe Oq do
 
   describe "with multiple YAML file input and slurp" do
     it "should return the correct output" do
-      run_binary(input: "", args: [".", "-c", "-i", "yaml", "-s", "spec/assets/data1.yml", "spec/assets/data2.yml"]) do |output|
+      run_binary(input: "", args: ["-c", "-i", "yaml", "-s", ".", "spec/assets/data1.yml", "spec/assets/data2.yml"]) do |output|
         output.should eq %([{"name":"Jim"},{"age":17}]\n)
       end
     end
@@ -109,7 +109,7 @@ describe Oq do
 
   describe "with STDIN YAML input and slurp" do
     it "should return the correct output" do
-      run_binary(input: "---\nname: Jim", args: [".", "-c", "-i", "yaml", "-s"]) do |output|
+      run_binary(input: "---\nname: Jim", args: ["-c", "-i", "yaml", "-s", "."]) do |output|
         output.should eq %([{"name":"Jim"}]\n)
       end
     end
@@ -117,7 +117,7 @@ describe Oq do
 
   describe "with YAML input and XML output" do
     it "should convert between formats" do
-      run_binary(input: "---\nfoo:\n  bar:\n    baz: 5\n", args: [".", "-i", "yaml", "-o", "xml"]) do |output|
+      run_binary(input: "---\nfoo:\n  bar:\n    baz: 5\n", args: ["-i", "yaml", "-o", "xml", "."]) do |output|
         output.should eq "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n  <foo>\n    <bar>\n      <baz>5</baz>\n    </bar>\n  </foo>\n</root>\n"
       end
     end
@@ -125,15 +125,15 @@ describe Oq do
 
   describe "with raw output" do
     it "should return the correct output" do
-      run_binary(input: "", args: [".", "-R", "-o", "yaml", "spec/assets/data1.json"]) do |output|
+      run_binary(input: "", args: ["-R", "-o", "yaml", ".", "spec/assets/data1.json"]) do |output|
         output.should eq %(--- '{"name": "Jim"}'\n)
       end
     end
   end
 
   describe "with the -c options" do
-    it "should compact the output" do
-      run_binary(input: NESTED_JSON_OBJECT, args: [".", "-c"]) do |output|
+    it "should return the correct output" do
+      run_binary(input: NESTED_JSON_OBJECT, args: ["-c", "."]) do |output|
         output.should eq %({"foo":{"bar":{"baz":5}}}\n)
       end
     end
@@ -147,10 +147,83 @@ describe Oq do
     end
   end
 
+  describe "with null input option" do
+    describe "with a scalar value" do
+      it "should return the correct output" do
+        run_binary(input: nil, args: ["-n", "0"]) do |output|
+          output.should eq "0\n"
+        end
+      end
+
+      it "should return the correct output" do
+        run_binary(input: nil, args: ["--null-input", "0"]) do |output|
+          output.should eq "0\n"
+        end
+      end
+    end
+
+    describe "with a JSON object string" do
+      it "should return the correct output" do
+        run_binary(input: nil, args: ["-cn", %([{"foo":"bar"},{"foo":"baz"}])]) do |output|
+          output.should eq %([{"foo":"bar"},{"foo":"baz"}]\n)
+        end
+      end
+    end
+
+    describe "with input from STDIN" do
+      it "should return the correct output" do
+        run_binary(input: "foo", args: ["-n"]) do |output|
+          output.should eq "null\n"
+        end
+      end
+    end
+  end
+
+  describe "with a custom indent value with JSON" do
+    it "should return the correct output" do
+      run_binary(input: SIMPLE_JSON_OBJECT, args: ["--indent", "1", "."]) do |output|
+        output.should eq %({\n "name": "Jim"\n}\n)
+      end
+    end
+  end
+
+  describe "with the --tab option" do
+    it "should return the correct output" do
+      run_binary(input: SIMPLE_JSON_OBJECT, args: ["--tab", "."]) do |output|
+        output.should eq %({\n\t"name": "Jim"\n}\n)
+      end
+    end
+  end
+
+  describe "with a custom indent value with XML" do
+    it "should return the correct output" do
+      run_binary(input: SIMPLE_JSON_OBJECT, args: ["--indent", "3", "-o", "xml", "."]) do |output|
+        output.should eq "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n   <name>Jim</name>\n</root>\n"
+      end
+    end
+  end
+
+  describe "with a custom XML root" do
+    it "should return the correct output" do
+      run_binary(input: SIMPLE_JSON_OBJECT, args: ["--xml-root", "friends", "-o", "xml", "."]) do |output|
+        output.should eq "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<friends>\n  <name>Jim</name>\n</friends>\n"
+      end
+    end
+  end
+
+  describe "when streaming input" do
+    it "should return the correct output" do
+      run_binary(input: %({"a": [1, 2.2, true, "abc", null]}), args: ["-nc", "--stream", "fromstream( 1|truncate_stream(inputs) |  select(length>1) | .[0] |= .[1:] )"]) do |output|
+        output.should eq %(1\n2.2\ntrue\n"abc"\nnull\n)
+      end
+    end
+  end
+
   describe "with XML input" do
     it "should return not implemented" do
-      run_binary(input: "", args: [".", "-i", "xml"]) do |output|
+      run_binary(input: "", args: ["-i", "xml", "."]) do |output, status|
         output.should eq "Not Implemented\n"
+        status.exit_code.should eq 1
       end
     end
   end
diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr
index 36f18e8..da270cc 100644
--- a/spec/spec_helper.cr
+++ b/spec/spec_helper.cr
@@ -11,11 +11,10 @@ def assert_builder_output(expected : String, &block : XML::Builder -> Nil) : Nil
 end
 
 # Runs the the binary with the given *name* and *args*.
-def run_binary(input : String, name : String = "bin/oq", args : Array(String) = [] of String, &block : String -> Nil)
+def run_binary(input : String?, name : String = "bin/oq", args : Array(String) = [] of String, &block : String, Process::Status -> Nil)
   buffer = IO::Memory.new
-  input = IO::Memory.new input
-  Process.run(name, args, error: buffer, output: buffer, input: input)
-  yield buffer.to_s
-  buffer.close
-  input.close
+  in = IO::Memory.new
+  in << input if input
+  status = Process.run(name, args, error: buffer, output: buffer, input: in.rewind)
+  yield buffer.to_s, status
 end
diff --git a/spec/to_xml_spec.cr b/spec/to_xml_spec.cr
index f29ceb8..14b2fa1 100644
--- a/spec/to_xml_spec.cr
+++ b/spec/to_xml_spec.cr
@@ -122,6 +122,14 @@ describe "#to_xml" do
       end
     end
 
+    describe "with multiple attribute objects" do
+      it "should convert correctly" do
+        assert_builder_output("<name>Jim</name><age unit=\"years\" some_key=\"-1\">12</age>") do |b|
+          {"name" => "Jim", "age" => {"@unit" => "years", "@some_key" => -1, "#text" => 12}}.to_xml b
+        end
+      end
+    end
+
     describe "with a nested attribute object" do
       it "should convert correctly" do
         assert_builder_output("<name>Jim</name><age><unit>years</unit>12</age>") do |b|
@@ -179,5 +187,13 @@ describe "#to_xml" do
         end
       end
     end
+
+    describe "with multiple attribute objects" do
+      it "should convert correctly" do
+        assert_builder_output("<name>Jim</name><age unit=\"years\" some_key=\"-1\">12</age>") do |b|
+          {"name": "Jim", "age": {"@unit": "years", "@some_key": -1, "#text": 12}}.to_xml b
+        end
+      end
+    end
   end
 end
diff --git a/src/oq.cr b/src/oq.cr
index cfbd75b..c5a83a8 100644
--- a/src/oq.cr
+++ b/src/oq.cr
@@ -3,7 +3,7 @@ require "yaml"
 
 require "./to_xml"
 
-# A performant, and portable jq wrapper to support formats other than JSON.
+# A performant and portable jq wrapper to support formats other than JSON.
 module Oq
   # The support formats that can be converted to/from.
   enum Format
@@ -27,31 +27,52 @@ module Oq
     # The root of the XML document when transcoding to XML.
     property xml_root : String = "root"
 
+    # The number of spaces to use for indentation.
+    property indent : Int32 = 2
+
+    # :nodoc:
+    property tab : Bool = false
+
     # :nodoc:
-    property slurp : Bool = false
+    property null_input : Bool = false
 
     # Consume the input, convert the input to JSON if needed, pass the input/args to `jq`, then convert the output if needed.
     def process
       input = IO::Memory.new
       output = IO::Memory.new
-      err = IO::Memory.new
+      error = IO::Memory.new
+
+      ARGV.replace ARGV - @args
 
       # Shift off the filter from ARGV
       @args << ARGV.shift unless ARGV.empty?
 
-      case @input_format
-      when .json? then input << ARGF.gets_to_end
-      when .yaml?
-        ARGV.empty? ? (input << YAML.parse(STDIN).to_json) : (ARGV.join('\n', input) { |f, io| io << YAML.parse(File.open(f)).to_json })
+      if !@null_input
+        case @input_format
+        when .json? then IO.copy(ARGF, input)
+        when .yaml?
+          ARGV.empty? ? (input << YAML.parse(STDIN).to_json) : (ARGV.join('\n', input) { |f, io| io << YAML.parse(File.open(f)).to_json })
+        else
+          STDERR.puts "Not Implemented"
+          exit(1)
+        end
+
+        input.rewind
       else
-        puts "Not Implemented"
-        exit(1)
+        @args = @args | ARGV
       end
 
-      run = Process.run("jq", args, input: input.rewind, output: output, error: err)
+      run = parallel(
+        Process.run("jq", args, input: input, output: output, error: error)
+      )
+
+      unless run[0].success?
+        if output.empty? && @null_input
+          puts "null"
+          exit
+        end
 
-      unless run.success?
-        puts err.to_s
+        STDERR.puts error.to_s
         exit(1)
       end
 
@@ -66,7 +87,7 @@ module Oq
       case @output_format
       when .json? then print io
       when .yaml? then print JSON.parse(io).to_yaml
-      when .xml?  then print JSON.parse(io).to_xml root: @xml_root
+      when .xml?  then print JSON.parse(io).to_xml root: @xml_root, indent: (@tab ? "\t" : " ")*@indent
       end
     end
   end
diff --git a/src/oq_cli.cr b/src/oq_cli.cr
index 8cafbd4..7a9d7f5 100644
--- a/src/oq_cli.cr
+++ b/src/oq_cli.cr
@@ -8,13 +8,17 @@ module Oq
   OptionParser.parse! do |parser|
     parser.banner = "Usage: oq [--help] [oq-arguments] [jq-arguments] jq_filter [file [files...]]"
     parser.on("--help", "Show this help message.") { puts parser; exit }
-    parser.on("-i FORMAT", "--input FORMAT", "Format of the input data. Supported formats: #{Format.names.map(&.downcase).join(", ")}.") { |format| (f = Format.parse?(format)) ? processor.input_format = f : (puts "Invalid input format: '#{format}'"; exit(1)) }
-    parser.on("-o FORMAT", "--output FORMAT", "Format of the output data. Supported formats: #{Format.names.map(&.downcase).join(", ")}.") { |format| (f = Format.parse?(format)) ? processor.output_format = f : (puts "Invalid output format: '#{format}'"; exit(1)) }
-    parser.on("--xml-root=ROOT", "Name of the root XML element if converting to XML.") { |r| processor.xml_root = r }
-    parser.on("-s", "--slurp", "Read (slurp) all inputs into an array then apply filter to it.") { processor.slurp = true; processor.args << "-s" }
+    parser.on("-i FORMAT", "--input FORMAT", "Format of the input data. Supported formats: json, yaml.") { |format| (f = Format.parse?(format)) ? processor.input_format = f : (puts "Invalid input format: '#{format}'"; exit(1)) }
+    parser.on("-o FORMAT", "--output FORMAT", "Format of the output data. Supported formats: json, yaml, xml.") { |format| (f = Format.parse?(format)) ? processor.output_format = f : (puts "Invalid output format: '#{format}'"; exit(1)) }
+    parser.on("--xml-root ROOT", "Name of the root XML element if converting to XML.") { |r| processor.xml_root = r }
+    parser.on("--indent NUMBER", "Use the given number of spaces for indentation (JSON/XML only).") { |n| processor.indent = n.to_i; processor.args << "--indent"; processor.args << n }
     parser.invalid_option do |flag|
+      case flag
+      when "-n", "--null-input" then processor.null_input = true
+      when "--tab"              then processor.tab = true
+      end
+
       processor.args << flag
-      ARGV.delete flag
     end
   end
 
diff --git a/src/to_xml.cr b/src/to_xml.cr
index fe63a43..5e7d87a 100644
--- a/src/to_xml.cr
+++ b/src/to_xml.cr
@@ -3,14 +3,14 @@ require "yaml"
 require "xml"
 
 class Object
-  def to_xml(*, root : String = "root") : String
+  def to_xml(*, root : String = "root", indent : String = "  ") : String
     String.build do |str|
-      to_xml str, root: root
+      to_xml str, root: root, indent: indent
     end
   end
 
-  def to_xml(io : IO, *, root : String?) : Nil
-    XML.build(io, indent: "  ", encoding: "utf-8") do |builder|
+  def to_xml(io : IO, *, root : String?, indent : String) : Nil
+    XML.build(io, indent: indent, encoding: "utf-8") do |builder|
       builder.element root do
         to_xml builder
       end