diff --git a/lib/apex/encoder/aprs_kiss.rb b/lib/apex/encoder/aprs_kiss.rb
index a22474334465a64366b973ae5d5b27ffaba6dd52..be3a85738bce288e39e030056c31aac507720f25 100644
--- a/lib/apex/encoder/aprs_kiss.rb
+++ b/lib/apex/encoder/aprs_kiss.rb
@@ -1,4 +1,3 @@
-require 'kiss/constants'
 require 'apex/frame'
 
 module Apex
@@ -7,137 +6,8 @@ module Apex
         protected
         def initialize(data_stream)
             @data_stream = data_stream
-            @lock = Mutex.new
         end
 
-        # private
-        # def self.decode_frame(raw_frame)
-        #     frame_len = raw_frame.length
-        #
-        #     if frame_len > 16
-        #         (0...frame_len - 2).each do |raw_slice|
-        #             # Is address field length correct?
-        #             if raw_frame[raw_slice] & 0x01 != 0 and ((raw_slice + 1) % 7) == 0
-        #                 i = (raw_slice.to_f + 1.0) / 7.0
-        #                 # Less than 2 callsigns?
-        #                 if 1.0 < i and i < 11.0
-        #                     if raw_frame[raw_slice + 1] & 0x03 == 0x03 and [0xf0, 0xcf].include? raw_frame[raw_slice + 2]
-        #                         payload_as_array = raw_frame[raw_slice + 3..-1].map { |b| b.chr }
-        #                         payload = payload_as_array.join
-        #                         destination = Apex::Frame::Entity.from_raw(identity_as_string(extract_callsign(raw_frame)))
-        #                         source = Apex::Frame::Entity.from_raw(identity_as_string(extract_callsign(raw_frame[7..-1])))
-        #                         path = extract_path(i.to_i, raw_frame)
-        #                         return Apex::Frame::Frame.new(source, destination, path, payload)
-        #                     end
-        #                 end
-        #             end
-        #         end
-        #     end
-        #     return nil
-        # end
-        #
-        # private
-        # def self.valid_frame(raw_frame)
-        #     frame_len = raw_frame.length
-        #
-        #     if frame_len > 16
-        #         (0...frame_len - 2).each do |raw_slice|
-        #             # Is address field length correct?
-        #             if raw_frame[raw_slice] & 0x01 != 0 and ((raw_slice + 1) % 7) == 0
-        #                 i = (raw_slice.to_f + 1.0) / 7.0
-        #                 # Less than 2 callsigns?
-        #                 if 1.0 < i and i < 11.0
-        #                     if raw_frame[raw_slice + 1] & 0x03 == 0x03 and [0xf0, 0xcf].include? raw_frame[raw_slice + 2]
-        #                         return true
-        #                     end
-        #                 end
-        #             end
-        #         end
-        #     end
-        #     return false
-        # end
-
-        # private
-        # def self.extract_path(start, raw_frame)
-        #     full_path = []
-        #
-        #     (2...start).each do |i|
-        #         path = identity_as_string(extract_callsign(raw_frame[i * 7..-1]))
-        #         if path and path.length > 0
-        #             if raw_frame[i * 7 + 6] & 0x80 != 0
-        #                 full_path << [path, '*'].join
-        #             else
-        #                 full_path << path
-        #             end
-        #         end
-        #     end
-        #     return Apex::Frame::Path.from_raw(full_path)
-        # end
-
-        # private
-        # def self.extract_callsign(raw_frame)
-        #     callsign_as_array = raw_frame[0...6].map { |x| (x >> 1).chr }
-        #     callsign = callsign_as_array.join.strip
-        #     ssid = (raw_frame[6] >> 1) & 0x0f
-        #     ssid = (ssid == nil or ssid == 0 ? nil : ssid)
-        #     return {:callsign => callsign, :ssid => ssid}
-        # end
-
-        # private
-        # def self.identity_as_string(identity)
-        #     if identity[:ssid] and identity[:ssid] > 0
-        #         return [identity[:callsign], identity[:ssid].to_s].join('-')
-        #     else
-        #         return identity[:callsign]
-        #     end
-        # end
-
-        # private
-        # def self.encode_frame(frame)
-        #     enc_frame = encode_callsign(parse_identity_string(frame.destination.to_s)) + encode_callsign(parse_identity_string(frame.source.to_s))
-        #
-        #     frame.path.each do |hop|
-        #         enc_frame += encode_callsign(parse_identity_string(hop.to_s))
-        #     end
-        #
-        #     return enc_frame[0...-1] + [enc_frame[-1] | 0x01] + [Kiss::SLOT_TIME] + [0xf0] + frame.payload.chars.map { |c| c.ord }
-        # end
-
-        # private
-        # def self.encode_callsign(callsign)
-        #     call_sign = callsign[:callsign]
-        #
-        #     enc_ssid = (callsign[:ssid] << 1) | 0x60
-        #
-        #     if call_sign.include? '*'
-        #         call_sign.gsub!(/\*/, '')
-        #         enc_ssid |= 0x80
-        #     end
-        #
-        #     while call_sign.length < 6
-        #         call_sign = [call_sign, ' '].join
-        #     end
-        #
-        #     return call_sign.chars.map { |p| p.ord << 1 } + [enc_ssid]
-        # end
-
-        # private
-        # def self.parse_identity_string(identity_string)
-        #     # If we are parsing a spent token then first lets get rid of the astresick suffix.
-        #     if identity_string[-1] == '*'
-        #         identity_string = identity_string[0..-1]
-        #     end
-        #
-        #     if identity_string.include? '-'
-        #         call_sign, ssid = identity_string.split('-')
-        #     else
-        #         call_sign = identity_string
-        #         ssid = 0
-        #     end
-        #
-        #     return {:callsign => call_sign, :ssid => ssid.to_i}
-        # end
-
         public
         def connect(*args, **kwargs)
             @data_stream.connect(*args, **kwargs)
@@ -150,24 +20,29 @@ module Apex
 
         public
         def read(*args, **kwargs)
-            # @lock.synchronize do
-            #     frame = @data_stream.read(*args, **kwargs)
-            #     if frame and frame.length > 0
-            #         return AprsKiss.decode_frame(frame)
-            #     else
-            #         return nil
-            #     end
-            # end
+          frame_map = @data_stream.read
+          return nil if frame_map.nil?
+
+          source = Apex::Frame::Entity.from_raw(frame_map[:source])
+          destination = Apex::Frame::Entity.from_raw(frame_map[:destination])
+
+          path = Apex::Frame::Path.from_raw(frame_map[:path])
+
+          return Apex::Frame::Frame.new(source, destination, path, frame_map[:payload])
         end
 
         public
         def write(frame, *args, **kwargs)
-            # @lock.synchronize do
-            #     encoded_frame = AprsKiss.encode_frame(frame)
-            #     if AprsKiss.valid_frame(encoded_frame)
-            #       @data_stream.write(encoded_frame, *args, **kwargs)
-            #     end
-            # end
+          raise ArgumentError.new("frame argument can not be nil") if frame.nil?
+
+          frame_map = {
+            :source => frame.source.to_s,
+            :destination => frame.destination.to_s,
+            :path => frame.path.to_string_array,
+            :payload => frame.payload
+          }
+
+          @data_stream.write(frame_map)
         end
     end
 end
diff --git a/lib/apex/frame/path.rb b/lib/apex/frame/path.rb
index e5cda75d387b0bf39aebc9e8e1745737b713ea05..0cf4979ce743dfe3f7f83160a5940e87a32c38d6 100644
--- a/lib/apex/frame/path.rb
+++ b/lib/apex/frame/path.rb
@@ -9,7 +9,8 @@ module Apex
         @path_array = []
         last_seen = true
         hops.each do |hop|
-          raise ArgumentError.new("All arguments must be of type Hop, and not nil") if (hop.nil?) || (not hop.kind_of? Apex::Frame::Hop)
+          raise ArgumentError.new("All arguments must not be nil: #{hops.to_s}") if (hop.nil?)
+          raise ArgumentError.new("All arguments must be of type Hop: #{hops.class.to_s}") if not hop.kind_of? Apex::Frame::Hop
           raise ArgumentError.new("A seen hop can not follow an unseen hop") if (hop.seen) && (!last_seen)
           last_seen = false if not hop.seen
           @path_array << hop
@@ -90,10 +91,17 @@ module Apex
         return @path_array.join(',')
       end
 
+      public
+      def to_string_array
+        return @path_array.map {|e| e.to_s}
+      end
+
+      public
       def unseen_hops
           @path_array.select { |hop| !hop.seen  }
       end
 
+      public
       def seen_hops
           @path_array.select { |hop| hop.seen  }
       end
diff --git a/spec/apex/encoder/aprs_kiss_spec.rb b/spec/apex/encoder/aprs_kiss_spec.rb
index d5cc94d1075c2aed4609c9ee63a13b29b5ccb023..747a38f52b3f94c4645d710551f87980c5dc4584 100644
--- a/spec/apex/encoder/aprs_kiss_spec.rb
+++ b/spec/apex/encoder/aprs_kiss_spec.rb
@@ -1,43 +1,60 @@
 require_relative '../../../lib/apex/encoder/aprs_kiss'
 require_relative '../../../lib/apex/frame'
 
-DECODED_FRAME_KISS = Apex::Frame::Frame.new(
+# DECODED_FRAME_KISS = Apex::Frame::Frame.new(
+#     Apex::Frame::Entity.from_raw('W2GMD-1'),
+#     Apex::Frame::Entity.from_raw('OMG'),
+#     Apex::Frame::Path.from_raw(['WIDE1-1', 'WIDE2-2']),
+#     'test_encode_frame'
+# )
+
+FRAME_KISS = Apex::Frame::Frame.new(
     Apex::Frame::Entity.from_raw('W2GMD-1'),
     Apex::Frame::Entity.from_raw('OMG'),
     Apex::Frame::Path.from_raw(['WIDE1-1', 'WIDE2-2']),
     'test_encode_frame'
 )
-ENCODED_FRAME_KISS = [158, 154, 142, 64, 64, 64, 96, 174, 100, 142, 154, 136, 64, 98, 174, 146, 136, 138, 98,
-                      64, 98, 174, 146, 136, 138, 100, 64, 101, 3, 240, 116, 101, 115, 116, 95, 101, 110, 99, 111, 100,
-                      101, 95, 102, 114, 97, 109, 101]
 
-ENCODED_FRAME_KISS_INVALID = [166, 110, 168, 166, 170, 172, 96, 150, 142, 108, 174, 168, 140, 96, 154, 168, 158,
-                              166, 158, 64, 100, 174, 146, 136, 138, 100, 226, 130, 164, 224, 150, 140, 108, 140, 146, 164,
-                              117, 3, 240, 96, 49, 55, 69, 108, 35, 88, 45, 47, 107, 103, 54, 119, 116, 102, 64, 103, 111,
-                              115, 115, 101, 108, 105, 110, 102, 97, 109, 105, 108, 121, 46, 99, 111, 109]
+FRAME_MAP = {
+  :source => 'W2GMD-1',
+  :destination => 'OMG',
+  :path => ['WIDE1-1', 'WIDE2-2'],
+  :payload => 'test_encode_frame'
+}
+# ENCODED_FRAME_KISS = [158, 154, 142, 64, 64, 64, 96, 174, 100, 142, 154, 136, 64, 98, 174, 146, 136, 138, 98,
+#                       64, 98, 174, 146, 136, 138, 100, 64, 101, 3, 240, 116, 101, 115, 116, 95, 101, 110, 99, 111, 100,
+#                       101, 95, 102, 114, 97, 109, 101]
+#
+# ENCODED_FRAME_KISS_INVALID = [166, 110, 168, 166, 170, 172, 96, 150, 142, 108, 174, 168, 140, 96, 154, 168, 158,
+#                               166, 158, 64, 100, 174, 146, 136, 138, 100, 226, 130, 164, 224, 150, 140, 108, 140, 146, 164,
+#                               117, 3, 240, 96, 49, 55, 69, 108, 35, 88, 45, 47, 107, 103, 54, 119, 116, 102, 64, 103, 111,
+#                               115, 115, 101, 108, 105, 110, 102, 97, 109, 105, 108, 121, 46, 99, 111, 109]
 
 describe Apex::AprsKiss do
+
   let(:data_stream) { double("data_stream") }
   let(:aprs_kiss) { Apex::AprsKiss.new(data_stream) }
+
   describe ".read" do
     context "Given a mocked data_stream with a valid Frame" do
       it "decodes a frame from the stream" do
-        expect(data_stream).to receive(:read).and_return(ENCODED_FRAME_KISS)
-        expect(aprs_kiss.read()).to eql(DECODED_FRAME_KISS)
+        expect(data_stream).to receive(:read).and_return(FRAME_MAP)
+        expect(aprs_kiss.read()).to eql(FRAME_KISS)
       end
     end
-    context "Given a mocked data_stream with an invalid frame" do
+    context "Given a mocked data_stream with no pending data" do
       it "returns nil" do
-        expect(data_stream).to receive(:read).and_return(ENCODED_FRAME_KISS_INVALID)
+        expect(data_stream).to receive(:read).and_return(nil)
         expect(aprs_kiss.read()).to be_nil
       end
     end
   end
+
   describe ".write" do
     context "Given a mocked data_stream with a valid Frame" do
       it "encodes a frame to the stream" do
-        expect(data_stream).to receive(:write).with(ENCODED_FRAME_KISS)
-        aprs_kiss.write(DECODED_FRAME_KISS)
+        expect(data_stream).to receive(:write).with(FRAME_MAP)
+        aprs_kiss.write(FRAME_KISS)
       end
     end
   end