var Maybe = require('data.maybe');

var Decoding = require('./nsnjson.decoding');

var Types = require('./nsnjson.types');

var Format = require('./nsnjson.format');

function ArrayStyleDecoding(customTypesDecoders) {
  this.customTypesDecoders = customTypesDecoders;
}

ArrayStyleDecoding.prototype = Object.create(Decoding.prototype);

ArrayStyleDecoding.prototype.getType = function(presentation) {
  var customTypesDecoders = this.customTypesDecoders;

  for (var type in customTypesDecoders) {
    if (customTypesDecoders.hasOwnProperty(type)) {
      var customDecoder = customTypesDecoders[type];

      with (customDecoder) {
        if (detector(presentation)) {
          return Maybe.Just(type);
        }
      }
    }
  }

  if (presentation.length == 0) {
    return Maybe.Just(Types.NULL);
  }

  switch (presentation[0]) {
    case Format.TYPE_MARKER_NUMBER:  return Maybe.Just(Types.NUMBER);
    case Format.TYPE_MARKER_STRING:  return Maybe.Just(Types.STRING);
    case Format.TYPE_MARKER_BOOLEAN: return Maybe.Just(Types.BOOLEAN);
    case Format.TYPE_MARKER_ARRAY:   return Maybe.Just(Types.ARRAY);
    case Format.TYPE_MARKER_OBJECT:  return Maybe.Just(Types.OBJECT);
  }

  return Maybe.Nothing();
}

ArrayStyleDecoding.prototype.decodeNull = function() {
  return Maybe.Just(null);
}

ArrayStyleDecoding.prototype.decodeNumber = function(presentation) {
  return Maybe.Just(presentation[1]);
}

ArrayStyleDecoding.prototype.decodeString = function(presentation) {
  return Maybe.Just(presentation[1]);
}

ArrayStyleDecoding.prototype.decodeBoolean = function(presentation) {
  switch (presentation[1]) {
    case 1: return Maybe.Just(true);
    case 0: return Maybe.Just(false);
  }

  return Maybe.Nothing();
}

ArrayStyleDecoding.prototype.decodeArray = function(presentation) {
  var array = [];

  for (var i = 1, size = presentation.length; i < size; i++) {
    var itemPresentation = presentation[i];

    var itemMaybe = this.decode(itemPresentation);

    if (itemMaybe.isJust) {
      var item = itemMaybe.get();

      array.push(item);
    }
  }

  return Maybe.Just(array);
}

ArrayStyleDecoding.prototype.decodeObject = function(presentation) {
  var object = {};

  for (var i = 1, size = presentation.length; i < size; i++) {
    var fieldPresentation = presentation[i];

    var name = fieldPresentation[0];

    var valueMaybe = this.decode(fieldPresentation[1]);

    if (valueMaybe.isJust) {
      var value = valueMaybe.get();

      object[name] = value;
    }
  }

  return Maybe.Just(object);
}

module.exports = ArrayStyleDecoding;
@@ -217,34 +217,27 @@
 %7B%0A  
-this.customTypesDecoders =
+Decoding.call(this,
  cus
@@ -252,16 +252,17 @@
 Decoders
+)
 ;%0A%7D%0A%0AArr
@@ -409,326 +409,117 @@
 Type
-sDecoders = this.customTypesDecoders;%0A%0A  for (var type in customTypesDecoders) %7B%0A    if (customTypesDecoders.hasOwnProperty(type)) %7B%0A      var customDecoder = customTypesDecoders%5Btype%5D;%0A%0A      with (customDecoder) %7B%0A        if (detector(presentation)) %7B%0A          return Maybe.Just(type);%0A        %7D%0A      %7D%0A    %7D%0A  %7D%0A%0A
+Maybe = Decoding.prototype.getType.call(this, presentation);%0A%0A  return customTypeMaybe.orElse(function() %7B%0A  
   if
@@ -544,24 +544,26 @@
 gth == 0) %7B%0A
+  
     return M
@@ -585,21 +585,25 @@
 .NULL);%0A
+  
   %7D%0A%0A
+  
   switch
@@ -623,24 +623,26 @@
 n%5B0%5D) %7B%0A    
+ 
+ 
 case Format.
@@ -695,16 +695,18 @@
 UMBER);%0A
+  
     case
@@ -767,16 +767,18 @@
 TRING);%0A
+  
     case
@@ -840,24 +840,26 @@
 OLEAN);%0A    
+  
 case Format.
@@ -911,16 +911,18 @@
 ARRAY);%0A
+  
     case
@@ -981,27 +981,31 @@
 .OBJECT);%0A  
+ 
+ 
 %7D%0A%0A
+  
   return May
@@ -1010,32 +1010,38 @@
 aybe.Nothing();%0A
+  %7D);%0A
 %7D%0A%0AArrayStyleDec

Refactor { ArrayStyleDecoding @ getType }