Decouple NULL and BOOLEAN
diff --git a/skeletons/NULL.c b/skeletons/NULL.c
index a43d412..076898e 100644
--- a/skeletons/NULL.c
+++ b/skeletons/NULL.c
@@ -5,7 +5,6 @@
 #include <asn_internal.h>
 #include <asn_codecs_prim.h>
 #include <NULL.h>
-#include <BOOLEAN.h>	/* Implemented in terms of BOOLEAN type */
 
 /*
  * NULL basic type description.
@@ -14,10 +13,10 @@
 	(ASN_TAG_CLASS_UNIVERSAL | (5 << 2))
 };
 asn_TYPE_operation_t asn_OP_NULL = {
-	BOOLEAN_free,
+	NULL_free,
 	NULL_print,
 	NULL_compare,
-	BOOLEAN_decode_ber,	/* Implemented in terms of BOOLEAN */
+	NULL_decode_ber,
 	NULL_encode_der,	/* Special handling of DER encoding */
 	NULL_decode_xer,
 	NULL_encode_xer,
@@ -51,6 +50,65 @@
 	0	/* No specifics */
 };
 
+void
+NULL_free(const asn_TYPE_descriptor_t *td, void *ptr,
+          enum asn_struct_free_method method) {
+    if(td && ptr) {
+        switch(method) {
+        case ASFM_FREE_EVERYTHING:
+            FREEMEM(ptr);
+            break;
+        case ASFM_FREE_UNDERLYING:
+            break;
+        case ASFM_FREE_UNDERLYING_AND_RESET:
+            memset(ptr, 0, sizeof(NULL_t));
+            break;
+        }
+    }
+}
+
+/*
+ * Decode NULL type.
+ */
+asn_dec_rval_t
+NULL_decode_ber(const asn_codec_ctx_t *opt_codec_ctx,
+                const asn_TYPE_descriptor_t *td, void **bool_value,
+                const void *buf_ptr, size_t size, int tag_mode) {
+    NULL_t *st = (NULL_t *)*bool_value;
+    asn_dec_rval_t rval;
+    ber_tlv_len_t length;
+
+    if(st == NULL) {
+        st = (NULL_t *)(*bool_value = CALLOC(1, sizeof(*st)));
+        if(st == NULL) {
+            rval.code = RC_FAIL;
+            rval.consumed = 0;
+            return rval;
+        }
+    }
+
+    ASN_DEBUG("Decoding %s as NULL (tm=%d)", td->name, tag_mode);
+
+    /*
+     * Check tags.
+     */
+    rval = ber_check_tags(opt_codec_ctx, td, 0, buf_ptr, size, tag_mode, 0,
+                          &length, 0);
+    if(rval.code != RC_OK) {
+        return rval;
+    }
+
+    // X.690-201508, #8.8.2, length shall be zero.
+    if(length != 0) {
+        ASN_DEBUG("Decoding %s as NULL failed: too much data", td->name);
+        rval.code = RC_FAIL;
+        rval.consumed = 0;
+        return rval;
+    }
+
+    return rval;
+}
+
 asn_enc_rval_t
 NULL_encode_der(const asn_TYPE_descriptor_t *td, const void *ptr, int tag_mode,
                 ber_tlv_tag_t tag, asn_app_consume_bytes_f *cb, void *app_key) {
diff --git a/skeletons/NULL.h b/skeletons/NULL.h
index 50f53ca..c8e05d2 100644
--- a/skeletons/NULL.h
+++ b/skeletons/NULL.h
@@ -6,23 +6,24 @@
 #define	ASN_TYPE_NULL_H
 
 #include <asn_application.h>
-#include <BOOLEAN.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 /*
- * The value of the NULL type is meaningless: see BOOLEAN if you want to
- * carry true/false semantics.
+ * The value of the NULL type is meaningless.
+ * Use the BOOLEAN type if you need to carry true/false semantics.
  */
 typedef int NULL_t;
 
 extern asn_TYPE_descriptor_t asn_DEF_NULL;
 extern asn_TYPE_operation_t asn_OP_NULL;
 
+asn_struct_free_f NULL_free;
 asn_struct_print_f NULL_print;
 asn_struct_compare_f NULL_compare;
+ber_type_decoder_f NULL_decode_ber;
 der_type_encoder_f NULL_encode_der;
 xer_type_decoder_f NULL_decode_xer;
 xer_type_encoder_f NULL_encode_xer;
@@ -32,8 +33,6 @@
 per_type_encoder_f NULL_encode_uper;
 asn_random_fill_f  NULL_random_fill;
 
-#define NULL_free	BOOLEAN_free
-#define NULL_decode_ber	BOOLEAN_decode_ber
 #define NULL_constraint	asn_generic_no_constraint
 
 #ifdef __cplusplus
diff --git a/skeletons/file-dependencies b/skeletons/file-dependencies
index 884e179..7d72fb8 100644
--- a/skeletons/file-dependencies
+++ b/skeletons/file-dependencies
@@ -16,7 +16,7 @@
 IA5String.h IA5String.c OCTET_STRING.h
 INTEGER.h INTEGER.c
 ISO646String.h ISO646String.c OCTET_STRING.h
-NULL.h NULL.c BOOLEAN.h
+NULL.h NULL.c
 NativeEnumerated.h NativeEnumerated.c NativeInteger.h
 NativeInteger.h NativeInteger.c INTEGER.h
 NativeReal.h NativeReal.c REAL.h