diff --git a/contrib/isn/Makefile b/contrib/isn/Makefile
index 75c07a8..96aaf35 100644
--- a/contrib/isn/Makefile
+++ b/contrib/isn/Makefile
@@ -6,6 +6,8 @@ EXTENSION = isn
 DATA = isn--1.0.sql isn--unpackaged--1.0.sql
 PGFILEDESC = "isn - data types for international product numbering standards"
 
+REGRESS = isn
+
 ifdef USE_PGXS
 PG_CONFIG = pg_config
 PGXS := $(shell $(PG_CONFIG) --pgxs)
diff --git a/contrib/isn/expected/isn.out b/contrib/isn/expected/isn.out
new file mode 100644
index 0000000..0e259d2
--- /dev/null
+++ b/contrib/isn/expected/isn.out
@@ -0,0 +1,222 @@
+--
+-- Test ISN extension
+--
+CREATE EXTENSION isn;
+--
+-- test valid conversions
+--
+SELECT '9780123456786'::EAN13, -- old book
+       '9790123456785'::EAN13, -- music
+       '9791234567896'::EAN13, -- new book
+       '9771234567898'::EAN13, -- serial
+       '0123456789012'::EAN13, -- upc
+       '1234567890128'::EAN13;
+       ean13       |       ean13       |      ean13      |       ean13       |      ean13      |      ean13      
+-------------------+-------------------+-----------------+-------------------+-----------------+-----------------
+ 978-0-12-345678-6 | 979-0-1234-5678-5 | 979-123456789-6 | 977-1234-567-89-8 | 012-345678901-2 | 123-456789012-8
+(1 row)
+
+SELECT '9780123456786'::ISBN,
+       '123456789X'::ISBN,
+       '9780123456786'::ISBN13::ISBN,
+       '9780123456786'::EAN13::ISBN;
+     isbn      |     isbn      |     isbn      |     isbn      
+---------------+---------------+---------------+---------------
+ 0-12-345678-9 | 1-234-56789-X | 0-12-345678-9 | 0-12-345678-9
+(1 row)
+
+SELECT -- new books, shown as ISBN13 even for ISBN...
+       '9791234567896'::ISBN,
+       '9791234567896'::ISBN13::ISBN,
+       '9791234567896'::EAN13::ISBN;
+      isbn       |      isbn       |      isbn       
+-----------------+-----------------+-----------------
+ 979-123456789-6 | 979-123456789-6 | 979-123456789-6
+(1 row)
+
+SELECT '9780123456786'::ISBN13,
+       '123456789X'::ISBN13,
+       '9791234567896'::ISBN13,
+       '9791234567896'::EAN13::ISBN13;
+      isbn13       |      isbn13       |     isbn13      |     isbn13      
+-------------------+-------------------+-----------------+-----------------
+ 978-0-12-345678-6 | 978-1-234-56789-7 | 979-123456789-6 | 979-123456789-6
+(1 row)
+
+SELECT '9790123456785'::ISMN,
+       '9790123456785'::EAN13::ISMN,
+       'M123456785'::ISMN,
+       'M-1234-5678-5'::ISMN;
+     ismn      |     ismn      |     ismn      |     ismn      
+---------------+---------------+---------------+---------------
+ M-1234-5678-5 | M-1234-5678-5 | M-1234-5678-5 | M-1234-5678-5
+(1 row)
+
+SELECT '9790123456785'::ISMN13,
+       'M123456785'::ISMN13,
+       'M-1234-5678-5'::ISMN13;
+      ismn13       |      ismn13       |      ismn13       
+-------------------+-------------------+-------------------
+ 979-0-1234-5678-5 | 979-0-1234-5678-5 | 979-0-1234-5678-5
+(1 row)
+
+SELECT '9771234567003'::ISSN,
+       '12345679'::ISSN;
+   issn    |   issn    
+-----------+-----------
+ 1234-5679 | 1234-5679
+(1 row)
+
+SELECT '9771234567003'::ISSN13,
+       '12345679'::ISSN13,
+       '9771234567898'::ISSN13,
+       '9771234567898'::EAN13::ISSN13;
+      issn13       |      issn13       |      issn13       |      issn13       
+-------------------+-------------------+-------------------+-------------------
+ 977-1234-567-00-3 | 977-1234-567-00-3 | 977-1234-567-89-8 | 977-1234-567-89-8
+(1 row)
+
+SELECT '0123456789012'::UPC,
+       '0123456789012'::EAN13::UPC;
+     upc      |     upc      
+--------------+--------------
+ 123456789012 | 123456789012
+(1 row)
+
+--
+-- test invalid checksums
+--
+SELECT '1234567890'::ISBN;
+ERROR:  invalid check digit for ISBN13 number: "1234567890", should be X
+LINE 1: SELECT '1234567890'::ISBN;
+               ^
+SELECT 'M123456780'::ISMN;
+ERROR:  invalid check digit for ISMN number: "M123456780", should be 5
+LINE 1: SELECT 'M123456780'::ISMN;
+               ^
+SELECT '12345670'::ISSN;
+ERROR:  invalid check digit for ISSN number: "12345670", should be 9
+LINE 1: SELECT '12345670'::ISSN;
+               ^
+SELECT '9780123456780'::ISBN;
+ERROR:  invalid check digit for ISBN13 number: "9780123456780", should be 6
+LINE 1: SELECT '9780123456780'::ISBN;
+               ^
+SELECT '9791234567890'::ISBN13;
+ERROR:  invalid check digit for ISBN13 number: "9791234567890", should be 6
+LINE 1: SELECT '9791234567890'::ISBN13;
+               ^
+SELECT '0123456789010'::UPC;
+ERROR:  invalid check digit for UPC number: "0123456789010", should be 2
+LINE 1: SELECT '0123456789010'::UPC;
+               ^
+SELECT '1234567890120'::EAN13;
+ERROR:  invalid check digit for EAN13 number: "1234567890120", should be 8
+LINE 1: SELECT '1234567890120'::EAN13;
+               ^
+--
+-- test invalid conversions
+--
+SELECT '9790123456785'::ISBN; -- not a book
+ERROR:  cannot cast ISMN to ISBN13 for number: "9790123456785"
+LINE 1: SELECT '9790123456785'::ISBN;
+               ^
+SELECT '9771234567898'::ISBN; -- not a book
+ERROR:  cannot cast ISSN to ISBN13 for number: "9771234567898"
+LINE 1: SELECT '9771234567898'::ISBN;
+               ^
+SELECT '0123456789012'::ISBN; -- not a book
+ERROR:  cannot cast UPC to ISBN13 for number: "0123456789012"
+LINE 1: SELECT '0123456789012'::ISBN;
+               ^
+SELECT '9790123456785'::ISBN13; -- not a book
+ERROR:  cannot cast ISMN to ISBN13 for number: "9790123456785"
+LINE 1: SELECT '9790123456785'::ISBN13;
+               ^
+SELECT '9771234567898'::ISBN13; -- not a book
+ERROR:  cannot cast ISSN to ISBN13 for number: "9771234567898"
+LINE 1: SELECT '9771234567898'::ISBN13;
+               ^
+SELECT '0123456789012'::ISBN13; -- not a book
+ERROR:  cannot cast UPC to ISBN13 for number: "0123456789012"
+LINE 1: SELECT '0123456789012'::ISBN13;
+               ^
+SELECT '9780123456786'::ISMN; -- not music
+ERROR:  cannot cast ISBN to ISMN for number: "9780123456786"
+LINE 1: SELECT '9780123456786'::ISMN;
+               ^
+SELECT '9771234567898'::ISMN; -- not music
+ERROR:  cannot cast ISSN to ISMN for number: "9771234567898"
+LINE 1: SELECT '9771234567898'::ISMN;
+               ^
+SELECT '9791234567896'::ISMN; -- not music
+ERROR:  cannot cast ISBN13 to ISMN for number: "9791234567896"
+LINE 1: SELECT '9791234567896'::ISMN;
+               ^
+SELECT '0123456789012'::ISMN; -- not music
+ERROR:  cannot cast UPC to ISMN for number: "0123456789012"
+LINE 1: SELECT '0123456789012'::ISMN;
+               ^
+SELECT '9780123456786'::ISSN; -- not serial
+ERROR:  cannot cast ISBN to ISSN for number: "9780123456786"
+LINE 1: SELECT '9780123456786'::ISSN;
+               ^
+SELECT '9790123456785'::ISSN; -- not serial
+ERROR:  cannot cast ISMN to ISSN for number: "9790123456785"
+LINE 1: SELECT '9790123456785'::ISSN;
+               ^
+SELECT '9791234567896'::ISSN; -- not serial
+ERROR:  cannot cast ISBN13 to ISSN for number: "9791234567896"
+LINE 1: SELECT '9791234567896'::ISSN;
+               ^
+SELECT '0123456789012'::ISSN; -- not serial
+ERROR:  cannot cast UPC to ISSN for number: "0123456789012"
+LINE 1: SELECT '0123456789012'::ISSN;
+               ^
+SELECT '9780123456786'::UPC; -- not a product
+ERROR:  cannot cast ISBN to UPC for number: "9780123456786"
+LINE 1: SELECT '9780123456786'::UPC;
+               ^
+SELECT '9771234567898'::UPC; -- not a product
+ERROR:  cannot cast ISSN to UPC for number: "9771234567898"
+LINE 1: SELECT '9771234567898'::UPC;
+               ^
+SELECT '9790123456785'::UPC; -- not a product
+ERROR:  cannot cast ISMN to UPC for number: "9790123456785"
+LINE 1: SELECT '9790123456785'::UPC;
+               ^
+SELECT '9791234567896'::UPC; -- not a product
+ERROR:  cannot cast ISBN13 to UPC for number: "9791234567896"
+LINE 1: SELECT '9791234567896'::UPC;
+               ^
+SELECT 'postgresql...'::EAN13;
+ERROR:  invalid input syntax for EAN13 number: "postgresql..."
+LINE 1: SELECT 'postgresql...'::EAN13;
+               ^
+SELECT 'postgresql...'::ISBN;
+ERROR:  invalid input syntax for ISBN13 number: "postgresql..."
+LINE 1: SELECT 'postgresql...'::ISBN;
+               ^
+SELECT 9780123456786::EAN13;
+ERROR:  cannot cast type bigint to ean13
+LINE 1: SELECT 9780123456786::EAN13;
+                            ^
+SELECT 9780123456786::ISBN;
+ERROR:  cannot cast type bigint to isbn
+LINE 1: SELECT 9780123456786::ISBN;
+                            ^
+--
+-- test some comparisons, must yield true
+--
+SELECT '12345679'::ISSN = '9771234567003'::EAN13 AS "ok",
+       'M-1234-5678-5'::ISMN = '9790123456785'::EAN13 AS "ok",
+       '9791234567896'::EAN13 != '123456789X'::ISBN AS "nope";
+ ok | ok | nope 
+----+----+------
+ t  | t  | t
+(1 row)
+
+--
+-- cleanup
+--
+DROP EXTENSION isn;
diff --git a/contrib/isn/isn.c b/contrib/isn/isn.c
index 4039824..04cc9f6 100644
--- a/contrib/isn/isn.c
+++ b/contrib/isn/isn.c
@@ -30,10 +30,14 @@ PG_MODULE_MAGIC;
 
 enum isn_type
 {
-	INVALID, ANY, EAN13, ISBN, ISMN, ISSN, UPC
+	/* ISBN is ISBN13 with an adaptative display */
+	INVALID, ANY, EAN13, ISBN13, ISBN, ISMN, ISSN, UPC
 };
 
-static const char *const isn_names[] = {"EAN13/UPC/ISxN", "EAN13/UPC/ISxN", "EAN13", "ISBN", "ISMN", "ISSN", "UPC"};
+static const char *const isn_names[] = {
+	"EAN13/UPC/ISxN", "EAN13/UPC/ISxN", "EAN13", "ISBN13",
+	"ISBN", "ISMN", "ISSN", "UPC"
+};
 
 static bool g_weak = false;
 static bool g_initialized = false;
@@ -366,7 +370,7 @@ ean2isn(ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
 
 	/* find out the data type: */
 	if (strncmp("978", buf, 3) == 0)
-	{							/* ISBN */
+	{							/* ISBN or ISBN-13 */
 		type = ISBN;
 	}
 	else if (strncmp("977", buf, 3) == 0)
@@ -379,7 +383,7 @@ ean2isn(ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
 	}
 	else if (strncmp("979", buf, 3) == 0)
 	{							/* ISBN-13 */
-		type = ISBN;
+		type = ISBN13;
 	}
 	else if (*buf == '0')
 	{							/* UPC */
@@ -389,7 +393,10 @@ ean2isn(ean13 ean, bool errorOK, ean13 *result, enum isn_type accept)
 	{
 		type = EAN13;
 	}
-	if (accept != ANY && accept != EAN13 && accept != type)
+	if (accept != ANY && accept != EAN13 && accept != type &&
+		/* also accept ISBN13 as ISBN... */
+		!((accept == ISBN13 && type == ISBN) ||
+		  (accept == ISBN && type == ISBN13)))
 		goto eanwrongtype;
 
 	*result = ret;
@@ -443,16 +450,22 @@ ean2ISBN(char *isn)
 	char	   *aux;
 	unsigned	check;
 
-	/* the number should come in this format: 978-0-000-00000-0 */
-	/* Strip the first part and calculate the new check digit */
-	hyphenate(isn, isn + 4, NULL, NULL);
-	check = weight_checkdig(isn, 10);
-	aux = strchr(isn, '\0');
-	while (!isdigit((unsigned char) *--aux));
-	if (check == 10)
-		*aux = 'X';
-	else
-		*aux = check + '0';
+	/* the number should come in this format: 978-0-000-00000-0
+	 * or may be an ISBN13 number...
+	 * Do the short output version only if possible.
+	 */
+	if (strncmp("978-", isn, 4) == 0)
+	{
+		/* Strip the first part and calculate the new check digit */
+		hyphenate(isn, isn + 4, NULL, NULL);
+		check = weight_checkdig(isn, 10);
+		aux = strchr(isn, '\0');
+		while (!isdigit((unsigned char) *--aux));
+		if (check == 10)
+			*aux = 'X';
+		else
+			*aux = check + '0';
+	}
 }
 
 static inline void
@@ -516,7 +529,8 @@ str2ean(const char *num)
  *				  the string (maximum MAXEAN13LEN+1 bytes)
  *				  This doesn't verify for a valid check digit.
  *
- * If shortType is true, the returned string is in the old ISxN short format.
+ * If shortType is true, the returned string is in the old ISxN short format
+ *    if possible, otherwise it is kept as a ISxN13 number.
  * If errorOK is false, ereport a useful error message if the string is bad.
  * If errorOK is true, just return "false" for bad input.
  */
@@ -571,7 +585,7 @@ ean2string(ean13 ean, bool errorOK, char *result, bool shortType)
 
 	/* find out what type of hyphenation is needed: */
 	if (strncmp("978-", result, search) == 0)
-	{							/* ISBN -13 978-range */
+	{							/* ISBN-13 978-range */
 		/* The string should be in this form: 978-??000000000-0" */
 		type = ISBN;
 		TABLE = ISBN_range;
@@ -594,7 +608,7 @@ ean2string(ean13 ean, bool errorOK, char *result, bool shortType)
 	else if (strncmp("979-", result, search) == 0)
 	{							/* ISBN-13 979-range */
 		/* The string should be in this form: 979-??000000000-0" */
-		type = ISBN;
+		type = ISBN13;
 		TABLE = ISBN_range_new;
 		TABLE_index = ISBN_index_new;
 	}
@@ -628,6 +642,8 @@ okay:
 	if (shortType)
 		switch (type)
 		{
+			case ISBN13: /* yep, accept ISBN13 number as short type... */
+				break;
 			case ISBN:
 				ean2ISBN(result);
 				break;
@@ -804,7 +820,10 @@ string2ean(const char *str, bool errorOK, ean13 *result,
 	/* obtain the real check digit value, validate, and convert to ean13: */
 	if (accept == EAN13 && type != accept)
 		goto eanwrongtype;
-	if (accept != ANY && type != EAN13 && type != accept)
+	if (accept != ANY && type != EAN13 && type != accept &&
+		/* yep, accept ISBN13 as ISBN... */
+		!((accept == ISBN13 && type == ISBN) ||
+		  (accept == ISBN && type == ISBN13)))
 		goto eanwrongtype;
 	switch (type)
 	{
@@ -816,12 +835,15 @@ string2ean(const char *str, bool errorOK, ean13 *result,
 			else if (strncmp("977", buf + 3, 3) == 0)
 				type = ISSN;
 			else if (strncmp("978", buf + 3, 3) == 0)
-				type = ISBN;
+				type = ISBN; /* or ISBN13 */
 			else if (strncmp("9790", buf + 3, 4) == 0)
 				type = ISMN;
 			else if (strncmp("979", buf + 3, 3) == 0)
-				type = ISBN;
-			if (accept != EAN13 && accept != ANY && type != accept)
+				type = ISBN13;
+			if (accept != EAN13 && accept != ANY && type != accept &&
+				/* yep, ISBN accepts ISBN13 numbers... */
+				!((accept == ISBN13 && type == ISBN) ||
+				  (accept == ISBN && type == ISBN13)))
 				goto eanwrongtype;
 			break;
 		case ISMN:
@@ -978,7 +1000,7 @@ ean13_in(PG_FUNCTION_ARGS)
 	PG_RETURN_EAN13(result);
 }
 
-/* isbn_in
+/* accept *ANY* isbn or isbn13 type
  */
 PG_FUNCTION_INFO_V1(isbn_in);
 Datum
@@ -987,7 +1009,7 @@ isbn_in(PG_FUNCTION_ARGS)
 	const char *str = PG_GETARG_CSTRING(0);
 	ean13		result;
 
-	(void) string2ean(str, false, &result, ISBN);
+	(void) string2ean(str, false, &result, ISBN13);
 	PG_RETURN_EAN13(result);
 }
 
@@ -1030,8 +1052,8 @@ upc_in(PG_FUNCTION_ARGS)
 	PG_RETURN_EAN13(result);
 }
 
-/* casting functions
-*/
+/* anything which is a book, ISBN or ISBN13, is accepted.
+ */
 PG_FUNCTION_INFO_V1(isbn_cast_from_ean13);
 Datum
 isbn_cast_from_ean13(PG_FUNCTION_ARGS)
@@ -1039,7 +1061,7 @@ isbn_cast_from_ean13(PG_FUNCTION_ARGS)
 	ean13		val = PG_GETARG_EAN13(0);
 	ean13		result;
 
-	(void) ean2isn(val, false, &result, ISBN);
+	(void) ean2isn(val, false, &result, ISBN13);
 
 	PG_RETURN_EAN13(result);
 }
diff --git a/contrib/isn/sql/isn.sql b/contrib/isn/sql/isn.sql
new file mode 100644
index 0000000..5ef6d8a
--- /dev/null
+++ b/contrib/isn/sql/isn.sql
@@ -0,0 +1,104 @@
+--
+-- Test ISN extension
+--
+
+CREATE EXTENSION isn;
+
+--
+-- test valid conversions
+--
+SELECT '9780123456786'::EAN13, -- old book
+       '9790123456785'::EAN13, -- music
+       '9791234567896'::EAN13, -- new book
+       '9771234567898'::EAN13, -- serial
+       '0123456789012'::EAN13, -- upc
+       '1234567890128'::EAN13;
+
+SELECT '9780123456786'::ISBN,
+       '123456789X'::ISBN,
+       '9780123456786'::ISBN13::ISBN,
+       '9780123456786'::EAN13::ISBN;
+
+SELECT -- new books, shown as ISBN13 even for ISBN...
+       '9791234567896'::ISBN,
+       '9791234567896'::ISBN13::ISBN,
+       '9791234567896'::EAN13::ISBN;
+
+SELECT '9780123456786'::ISBN13,
+       '123456789X'::ISBN13,
+       '9791234567896'::ISBN13,
+       '9791234567896'::EAN13::ISBN13;
+
+SELECT '9790123456785'::ISMN,
+       '9790123456785'::EAN13::ISMN,
+       'M123456785'::ISMN,
+       'M-1234-5678-5'::ISMN;
+
+SELECT '9790123456785'::ISMN13,
+       'M123456785'::ISMN13,
+       'M-1234-5678-5'::ISMN13;
+
+SELECT '9771234567003'::ISSN,
+       '12345679'::ISSN;
+
+SELECT '9771234567003'::ISSN13,
+       '12345679'::ISSN13,
+       '9771234567898'::ISSN13,
+       '9771234567898'::EAN13::ISSN13;
+
+SELECT '0123456789012'::UPC,
+       '0123456789012'::EAN13::UPC;
+
+--
+-- test invalid checksums
+--
+SELECT '1234567890'::ISBN;
+SELECT 'M123456780'::ISMN;
+SELECT '12345670'::ISSN;
+SELECT '9780123456780'::ISBN;
+SELECT '9791234567890'::ISBN13;
+SELECT '0123456789010'::UPC;
+SELECT '1234567890120'::EAN13;
+
+--
+-- test invalid conversions
+--
+SELECT '9790123456785'::ISBN; -- not a book
+SELECT '9771234567898'::ISBN; -- not a book
+SELECT '0123456789012'::ISBN; -- not a book
+
+SELECT '9790123456785'::ISBN13; -- not a book
+SELECT '9771234567898'::ISBN13; -- not a book
+SELECT '0123456789012'::ISBN13; -- not a book
+
+SELECT '9780123456786'::ISMN; -- not music
+SELECT '9771234567898'::ISMN; -- not music
+SELECT '9791234567896'::ISMN; -- not music
+SELECT '0123456789012'::ISMN; -- not music
+
+SELECT '9780123456786'::ISSN; -- not serial
+SELECT '9790123456785'::ISSN; -- not serial
+SELECT '9791234567896'::ISSN; -- not serial
+SELECT '0123456789012'::ISSN; -- not serial
+
+SELECT '9780123456786'::UPC; -- not a product
+SELECT '9771234567898'::UPC; -- not a product
+SELECT '9790123456785'::UPC; -- not a product
+SELECT '9791234567896'::UPC; -- not a product
+
+SELECT 'postgresql...'::EAN13;
+SELECT 'postgresql...'::ISBN;
+SELECT 9780123456786::EAN13;
+SELECT 9780123456786::ISBN;
+
+--
+-- test some comparisons, must yield true
+--
+SELECT '12345679'::ISSN = '9771234567003'::EAN13 AS "ok",
+       'M-1234-5678-5'::ISMN = '9790123456785'::EAN13 AS "ok",
+       '9791234567896'::EAN13 != '123456789X'::ISBN AS "nope";
+
+--
+-- cleanup
+--
+DROP EXTENSION isn;
