Improve KoralQuery Import
diff --git a/lib/Krawfish/Koral/Query.pm b/lib/Krawfish/Koral/Query.pm
index 07193a5..b9b0721 100644
--- a/lib/Krawfish/Koral/Query.pm
+++ b/lib/Krawfish/Koral/Query.pm
@@ -1,12 +1,13 @@
 package Krawfish::Koral::Query;
 use parent 'Krawfish::Info';
 use Krawfish::Koral::Query::Builder;
-use strict;
+use Krawfish::Koral::Query::Importer;
 use warnings;
+use strict;
 
 sub new {
   my $class = shift;
-  bless {
+  my $self = bless {
     any => 0,
     optional => 0,
     null => 0,
@@ -15,6 +16,12 @@
     extended_left => 0,
     extended_right => 0
   }, $class;
+
+  if ($_[0]) {
+    return $self->from_koral(shift);
+  };
+
+  $self;
 };
 
 #########################################
@@ -80,8 +87,34 @@
 #############################
 
 # Deserialization of KoralQuery
+# TODO: export this method from Importer
 sub from_koral {
-  ...
+  my ($class, $kq) = @_;
+  my $importer = Krawfish::Koral::Query::Importer->new;
+
+  my $type = $kq->{'@type'};
+  if ($type eq 'koral:group') {
+    my $op = $kq->{operation};
+    if ($op eq 'operation:sequence') {
+      return $importer->seq($kq);
+    }
+
+    elsif ($op eq 'operation:class') {
+      return $importer->class($kq);
+    }
+    else {
+      warn 'Operation ' . $op . ' not supported';
+    };
+  }
+
+  elsif ($type eq 'koral:token') {
+    return $importer->token($kq);
+  }
+  else {
+    warn $type . ' unknown';
+  };
+
+  return;
 };
 
 # Overwritten
@@ -98,6 +131,11 @@
   return Krawfish::Koral::Query::Builder->new;
 };
 
+# Create KoralQuery builder
+sub importer {
+  return Krawfish::Koral::Query::Importer->new;
+};
+
 1;
 
 
diff --git a/lib/Krawfish/Koral/Query/Class.pm b/lib/Krawfish/Koral/Query/Class.pm
index e7263ae..343ff96 100644
--- a/lib/Krawfish/Koral/Query/Class.pm
+++ b/lib/Krawfish/Koral/Query/Class.pm
@@ -95,4 +95,17 @@
 
 sub is_classed { 1 };
 
+
+sub from_koral {
+  my ($class, $kq) = @_;
+  my $importer = $class->importer;
+
+  my $nr = $kq->{'classOut'} or warn 'No class defined';
+
+  # Import operand
+  my $op = $importer->all($kq->{operands}->[0]);
+
+  return $class->new($op, $nr);
+};
+
 1;
diff --git a/lib/Krawfish/Koral/Query/Importer.pm b/lib/Krawfish/Koral/Query/Importer.pm
new file mode 100644
index 0000000..bc196c6
--- /dev/null
+++ b/lib/Krawfish/Koral/Query/Importer.pm
@@ -0,0 +1,41 @@
+package Krawfish::Koral::Query::Importer;
+use Krawfish::Koral::Query;
+use Krawfish::Koral::Query::Sequence;
+use Krawfish::Koral::Query::Token;
+use Krawfish::Koral::Query::Term;
+use Krawfish::Koral::Query::Class;
+use warnings;
+use strict;
+
+sub new {
+  my $var;
+  bless \$var, shift;
+};
+
+sub all {
+  shift;
+  return Krawfish::Koral::Query->from_koral(shift);
+};
+
+sub seq {
+  shift;
+  return Krawfish::Koral::Query::Sequence->from_koral(shift);
+};
+
+sub token {
+  shift;
+  return Krawfish::Koral::Query::Token->from_koral(shift);
+}
+
+sub term {
+  shift;
+  return Krawfish::Koral::Query::Term->from_koral(shift);
+};
+
+
+sub class {
+  shift;
+  return Krawfish::Koral::Query::Class->from_koral(shift);
+}
+
+1;
diff --git a/lib/Krawfish/Koral/Query/Sequence.pm b/lib/Krawfish/Koral/Query/Sequence.pm
index b95ee9e..dbe564d 100644
--- a/lib/Krawfish/Koral/Query/Sequence.pm
+++ b/lib/Krawfish/Koral/Query/Sequence.pm
@@ -185,6 +185,16 @@
   return join '', map { $_->to_string } @{$_[0]->{array}};
 };
 
+sub from_koral {
+  my $class = shift;
+  my $kq = shift;
+
+  my $importer = $class->importer;
+
+  return $class->new(
+    map { $importer->all($_) } @{$kq->{operands}}
+  );
+};
 
 1;
 
diff --git a/lib/Krawfish/Koral/Query/Span.pm b/lib/Krawfish/Koral/Query/Span.pm
index bfc2ebf..e03ef7f 100644
--- a/lib/Krawfish/Koral/Query/Span.pm
+++ b/lib/Krawfish/Koral/Query/Span.pm
@@ -55,6 +55,9 @@
 
 sub maybe_unsorted { 0 };
 
+sub from_koral;
+# Todo: Change the term_type!
+
 sub to_string {
   return '<' . $_[0]->wrap->to_string . '>';
 };
diff --git a/lib/Krawfish/Koral/Query/Term.pm b/lib/Krawfish/Koral/Query/Term.pm
index f648c30..39a1196 100644
--- a/lib/Krawfish/Koral/Query/Term.pm
+++ b/lib/Krawfish/Koral/Query/Term.pm
@@ -63,10 +63,27 @@
 
 sub term_type {
   my $self = shift;
-  return 'token'     unless $self->prefix;
-  return 'span'      if $self->prefix eq '<>';
-  return 'attribute' if $self->prefix eq '@';
-  return 'relation';
+  if ($_[0]) {
+    if ($_[0] eq 'span') {
+      $self->prefix('<>');
+    }
+    elsif ($_[0] eq 'attribute') {
+      $self->prefix('@');
+    }
+    elsif ($_[0] eq 'relation') {
+
+      # Todo: This doesn't respect
+      # direction
+      $self->prefix('>');
+    };
+    return $self;
+  }
+  else {
+    return 'token'     unless $self->prefix;
+    return 'span'      if $self->prefix eq '<>';
+    return 'attribute' if $self->prefix eq '@';
+    return 'relation';
+  };
 };
 
 
@@ -91,11 +108,27 @@
 
 # Operation
 sub match {
-  if ($_[1]) {
-    $_[0]->[4] = $_[1];
-    return $_[0];
+  my $self = shift;
+  if ($_[0]) {
+    my $match = shift;
+
+    if ($match =~ s/^match://) {
+      if ($match eq 'eq') {
+        $match = '=';
+      }
+      elsif ($match eq 'ne') {
+        $match = '!=';
+      }
+      else {
+        warn 'Unknown match';
+        return;
+      }
+    };
+
+    $self->[4] = $match;
+    return $self;
   };
-  $_[0]->[4] // '=';
+  $self->[4] // '=';
 };
 
 
@@ -136,6 +169,10 @@
   $hash->{layer} = $self->layer if $self->layer;
   $hash->{value} = $self->value if $self->value;
 
+  if ($self->match eq '!=') {
+    $hash->{match} = 'match:ne';
+  };
+
   # TODO: REGEX!
 
   return $hash;
@@ -255,4 +292,17 @@
 sub is_extended_left { 0 };
 sub maybe_unsorted { 0 };
 
+sub from_koral {
+  my $class = shift;
+  my $kq = shift;
+  my $term = $class->new;
+  $term->foundry('' . $kq->{foundry}) if $kq->{foundry};
+  $term->layer('' . $kq->{layer}) if $kq->{layer};
+  $term->key('' . $kq->{key}) if $kq->{key};
+  $term->match('' . $kq->{match}) if $kq->{match};
+
+  # TODO: Support deserialization of regex!
+  return $term;
+};
+
 1;
diff --git a/lib/Krawfish/Koral/Query/Token.pm b/lib/Krawfish/Koral/Query/Token.pm
index a47f93c..33957d8 100644
--- a/lib/Krawfish/Koral/Query/Token.pm
+++ b/lib/Krawfish/Koral/Query/Token.pm
@@ -7,8 +7,6 @@
 use warnings;
 use Scalar::Util qw/blessed/;
 
-# TODO: Support multiple tokens in a term group!
-
 sub new {
   my $class = shift;
   my $token = shift;
@@ -104,5 +102,29 @@
 
 sub maybe_unsorted { 0 };
 
+sub from_koral {
+  my $class = shift;
+  my $kq = shift;
+  my $importer = $class->importer;
+
+  # No wrap
+  unless ($kq->{'wrap'}) {
+    return $class->new;
+  }
+
+  # Wrap is a term
+  else {
+    my $wrap = $kq->{wrap};
+    if ($wrap->{'@type'} eq 'koral:term') {
+      return $class->new($importer->term($wrap));
+    }
+    elsif ($wrap->{'@type'} eq 'koral:termGroup') {
+      return $class->new($importer->term_group($wrap));
+    }
+    else {
+      warn 'Wrap type not supported!'
+    };
+  }
+};
 
 1;
diff --git a/t/koral/deserialization.t b/t/koral/deserialization.t
index fc4b839..d6ba2f2 100644
--- a/t/koral/deserialization.t
+++ b/t/koral/deserialization.t
@@ -5,11 +5,59 @@
 use Mojo::Util qw/slurp/;
 use Data::Dumper;
 
-use_ok('Krawfish::Koral');
+use_ok('Krawfish::Koral::Query');
 
 # deserialize import document
-my $doc_1 = slurp('t/data/doc1.jsonld');
-my $koral = Krawfish::Koral->new(decode_json($doc_1));
+# my $doc_1 = slurp('t/data/doc1.jsonld');
+# my $koral = Krawfish::Koral->new(decode_json($doc_1));
+
+my $query = Krawfish::Koral::Query->from_koral(
+  {
+    '@type' => 'koral:group',
+    'operation' => 'operation:sequence',
+    'operands' => [
+      {
+        '@type' => 'koral:token',
+        'wrap' => {
+          '@type' => 'koral:term',
+          'foundry' => 'tt',
+          'key' => 'NN',
+          'layer' => 'p',
+          'match' => 'match:eq'
+        }
+      },{
+        '@type' => 'koral:group',
+        'classOut' => 2,
+        'operation' => 'operation:class',
+        'operands' => [
+          {
+            '@type' => 'koral:token',
+            'wrap' => {
+              '@type' => 'koral:term',
+              'foundry' => 'tt',
+              'key' => 'NN',
+              'layer' => 'p',
+              'match' => 'match:ne'
+            }
+          }
+        ]
+      }
+    ]
+  }
+);
+
+
+
+
+is(my $deserialized = $query->to_string, '[tt/p=NN]{2:[tt/p!=NN]}', 'Stringification');
+
+ok(my $fragment = $query->to_koral_fragment, 'Get parsed fragment');
+
+ok(my $serialized = Krawfish::Koral::Query->from_koral($fragment), 'Parse serialization');
+
+is($deserialized, $serialized->to_string, 'In/Out equivalence');
+
+diag 'Test Further';
 
 done_testing;