diff --git a/VERSION b/VERSION
index faef31a4357c48d6e4c55e84c8be8e3bc9055e20..01781720cd4974d0bb8f69fc7c8c1c7933712679 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.7.0
+0.99.0
diff --git a/examples/rawexample_filtermcpl.c b/examples/rawexample_filtermcpl.c
index be890b66b10c92227dd39f555caa7f8d80d50050..98208186b5a07d00fdfe5b9dc21ac1c0c929de78 100644
--- a/examples/rawexample_filtermcpl.c
+++ b/examples/rawexample_filtermcpl.c
@@ -30,7 +30,7 @@ int main(int argc,char**argv) {
   mcpl_file_t fi = mcpl_open_file(infilename);
   mcpl_outfile_t fo = mcpl_create_outfile(outfilename);
   mcpl_transfer_metadata(fi, fo);
-  mcpl_hdr_add_comment(fo,"Applied custom filter to select neutrons with ekin<100eV");
+  mcpl_hdr_add_comment(fo,"Applied custom filter to select neutrons with ekin<100keV");
 
   //Loop over particles from input, only triggering mcpl_add_particle calls for
   //the chosen particles:
diff --git a/examples/rawexample_readmcpl.c b/examples/rawexample_readmcpl.c
index 7cd15337eaa55aba4dcf59e2ded04d8de0f5b710..4bfa2145e69c08a5200eab6937f6c868ae150ebb 100644
--- a/examples/rawexample_readmcpl.c
+++ b/examples/rawexample_readmcpl.c
@@ -32,7 +32,7 @@ int main(int argc,char**argv) {
   printf("Opened MCPL file produced with %s\n",mcpl_hdr_srcname(f));
   for (unsigned i = 0; i < mcpl_hdr_ncomments(f); ++i)
     printf("file had comment: '%s'\n",mcpl_hdr_comment(f,i));
-  printf("File containts %llu particles\n",(unsigned long long)mcpl_hdr_nparticles(f));
+  printf("File contains %llu particles\n",(unsigned long long)mcpl_hdr_nparticles(f));
 
   //Now, loop over particles and print some info:
 
diff --git a/src/mcpl/mcpl.c b/src/mcpl/mcpl.c
index 8c1c43b7bac2c61f50c3be7bcddf730280f89278..e01daa7e791115557032dcade050ae736b08d58a 100644
--- a/src/mcpl/mcpl.c
+++ b/src/mcpl/mcpl.c
@@ -32,6 +32,8 @@
 //                                                                                 //
 //  This file can be freely used as per the terms in the LICENSE file.             //
 //                                                                                 //
+//  Find more information and updates at https://mctools.github.io/mcpl/           //
+//                                                                                 //
 //  Written by Thomas Kittelmann, 2015-2016.                                       //
 //                                                                                 //
 /////////////////////////////////////////////////////////////////////////////////////
@@ -39,14 +41,6 @@
 
 //////
 //
-// TODO:
-//  * Implement --ignore flag for --merge.
-//
-// Planned features delayed for next release (not implemented yet):
-//  * Don't require code to calloc and keep track of their own mcpl_particle_t instance.
-//  * mcpl_gzip_file and mcpl_closeandgzip_outfile must return status indicating
-//    success or not (to know if .mcpl or .mcpl.gz file is the result).
-//
 //Possible future developments:
 //
 //  1) Support for particle groups ("events"). The file writing interface would
@@ -92,7 +86,7 @@
 // 8) Consider writing .mcpl.gz files directly (through a large buffer
 //    presumably). Or to have compressed blocks internally.
 //
-// 9) Should use unsigned char* rather than char* for buffers.
+// 9) Should use unsigned char* rather than char* for buffers?
 //
 //////
 
@@ -1515,11 +1509,12 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("Usage:\n");
   printf("  %s [dump-options] FILE\n",progname);
   printf("  %s --merge [merge-options] FILE1 FILE2\n",progname);
+  printf("  %s --extract [extract-options] FILE1 FILE2\n",progname);
   printf("  %s --repair FILE\n",progname);
   printf("  %s --version\n",progname);
   printf("  %s --help\n",progname);
   printf("\n");
-  printf("Dump Options:\n");
+  printf("Dump options:\n");
   printf("  By default include the info in the FILE header plus the first ten contained\n");
   printf("  particles. Modify with the following options:\n");
   assert(MCPLIMP_TOOL_DEFAULT_NLIMIT==10);
@@ -1530,13 +1525,17 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("  -sN             : Skip past the first N particles in the file (default %i).\n",MCPLIMP_TOOL_DEFAULT_NSKIP);
   printf("  -bKEY           : Dump binary blob stored under KEY to standard output.\n");
   printf("\n");
-  printf("Merge Options:\n");
+  printf("Merge options:\n");
   printf("  -m, --merge FILE1 FILE2\n");
   printf("                    Appends the particle contents in FILE2 to the end of FILE1.\n");
-  printf("                    Note that this will fail unless FILE1 and FILE2 have iden-\n");
-  printf("                    tical headers (but see option --ignore below).\n");
-  printf("  -i, --ignore      Ignore comments and binary blobs in FILE2. This allows some\n");
-  printf("                    otherwise forbidden merges, but some info might get lost.\n");
+  printf("                    Note that this will fail unless FILE1 and FILE2 have compa-\n");
+  printf("                    tible headers.\n");
+  printf("\n");
+  printf("Extract options:\n");
+  printf("  -e, --extract FILE1 FILE2\n");
+  printf("                    Extracts particles from FILE1 into a new FILE2.\n");
+  printf("  -lN, -sN          Select range of particles in FILE1 (as above).\n");
+  printf("  -pPDGCODE         select particles of type given by PDGCODE.\n");
   printf("\n");
   printf("Other options:\n");
   printf("  -r, --repair FILE\n");
@@ -1548,16 +1547,45 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   return 0;
 }
 
+int mcpl_str2int(const char* str, size_t len, int64_t* res)
+{
+  //portable 64bit str2int with error checking.
+  *res = 0;
+  if (!len)
+    len=strlen(str);
+  if (!len)
+    return 0;
+  int sign = 1;
+  if (str[0]=='-') {
+    sign = -1;
+    len -= 1;
+    str += 1;
+  }
+  int64_t tmp = 0;
+  for (size_t i=0; i<len; ++i) {
+    if (str[i]<'0'||str[i]>'9') {
+      return 0;
+    }
+    tmp *= 10;
+    tmp += str[i] - '0';
+  }
+  if (tmp > INT64_MAX)
+    return 0;
+  *res = sign * tmp;
+  return 1;
+}
+
 int mcpl_tool(int argc,char** argv) {
   const char * filename1 = 0;
   const char * filename2 = 0;
   const char * blobkey = 0;
+  const char * pdgcode_str = 0;
   int opt_justhead = 0;
   int opt_nohead = 0;
   int64_t opt_num_limit = -1;
   int64_t opt_num_skip = -1;
   int opt_merge = 0;
-  int opt_ignore = 0;
+  int opt_extract = 0;
   int opt_repair = 0;
   int opt_version = 0;
 
@@ -1585,18 +1613,26 @@ int mcpl_tool(int argc,char** argv) {
           blobkey = a+j+1;
           break;
         }
+        if (a[j]=='p') {
+          if (pdgcode_str)
+            return mcpl_tool_usage(argv,"-p specified more than once");
+          if (j+1==n)
+            return mcpl_tool_usage(argv,"Missing argument for -p");
+          pdgcode_str = a+j+1;
+          break;
+        }
+
         switch(a[j]) {
           case 'h': return mcpl_tool_usage(argv,0);
           case 'j': opt_justhead = 1; break;
           case 'n': opt_nohead = 1; break;
           case 'm': opt_merge = 1; break;
-          case 'i': opt_ignore = 1; break;
+          case 'e': opt_extract = 1; break;
           case 'r': opt_repair = 1; break;
           case 'v': opt_version = 1; break;
           case 'l': consume_digit = &opt_num_limit; break;
           case 's': consume_digit = &opt_num_skip; break;
           default:
-            printf("%c\n",a[j]);
             return mcpl_tool_usage(argv,"Unrecognised option");
         }
         if (consume_digit) {
@@ -1612,7 +1648,7 @@ int mcpl_tool(int argc,char** argv) {
       const char * lo_justhead = "justhead";
       const char * lo_nohead = "nohead";
       const char * lo_merge = "merge";
-      const char * lo_ignore = "ignore";
+      const char * lo_extract = "extract";
       const char * lo_repair = "repair";
       const char * lo_version = "version";
       //Use strstr instead of "strcmp(a,"--help")==0" to support shortened
@@ -1621,7 +1657,7 @@ int mcpl_tool(int argc,char** argv) {
       else if (strstr(lo_justhead,a)==lo_justhead) opt_justhead = 1;
       else if (strstr(lo_nohead,a)==lo_nohead) opt_nohead = 1;
       else if (strstr(lo_merge,a)==lo_merge) opt_merge = 1;
-      else if (strstr(lo_ignore,a)==lo_ignore) opt_ignore = 1;
+      else if (strstr(lo_extract,a)==lo_extract) opt_extract = 1;
       else if (strstr(lo_repair,a)==lo_repair) opt_repair = 1;
       else if (strstr(lo_version,a)==lo_version) opt_version = 1;
       else return mcpl_tool_usage(argv,"Unrecognised option");
@@ -1635,10 +1671,17 @@ int mcpl_tool(int argc,char** argv) {
       return mcpl_tool_usage(argv,"Bad arguments");
     }
   }
-  int number_dumpopts = (opt_justhead + opt_nohead + (opt_num_limit!=-1) + (opt_num_skip!=-1) + (blobkey!=0));
+
+  if ( opt_extract==0 && pdgcode_str )
+    return mcpl_tool_usage(argv,"-p can only be used with --extract.");
+
+  int number_dumpopts = (opt_justhead + opt_nohead + (blobkey!=0));
+  if (opt_extract==0)
+    number_dumpopts += (opt_num_limit!=-1) + (opt_num_skip!=-1);
   int any_dumpopts = number_dumpopts != 0;
-  int any_mergeopts = (opt_merge + opt_ignore)!=0;
-  if (any_dumpopts+any_mergeopts+opt_repair+opt_version>1)
+  int any_extractopts = (opt_extract!=0||pdgcode_str!=0);
+  int any_mergeopts = (opt_merge!=0);
+  if (any_dumpopts+any_mergeopts+any_extractopts+opt_repair+opt_version>1)
     return mcpl_tool_usage(argv,"Conflicting options specified.");
 
   if (blobkey&&(number_dumpopts>1))
@@ -1651,14 +1694,9 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
-  if (opt_ignore&&!opt_merge)
-    return mcpl_tool_usage(argv,"Use --ignore only with --merge.");
-
   if (opt_merge) {
     if (!filename2)
       return mcpl_tool_usage(argv,"Must specify two input files with --merge.");
-    if (opt_ignore)
-      return mcpl_tool_usage(argv,"--ignore is not implemented yet.");
 
     if (!mcpl_can_merge(filename1,filename2))
       return mcpl_tool_usage(argv,"Requested files are incompatible for merge as they have different header info.");
@@ -1667,6 +1705,53 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
+  if (opt_extract) {
+    if (!filename2)
+      return mcpl_tool_usage(argv,"Must specify both input and output files with --extract.");
+
+    mcpl_file_t fi = mcpl_open_file(filename1);
+    mcpl_outfile_t fo = mcpl_create_outfile(filename2);
+    mcpl_transfer_metadata(fi, fo);
+    uint64_t fi_nparticles = mcpl_hdr_nparticles(fi);
+
+    char comment[1024];
+    sprintf(comment, "mcpltool: extracted particles from file with %" PRIu64 " particles",fi_nparticles);
+    mcpl_hdr_add_comment(fo,comment);
+
+    int32_t pdgcode_select = 0;
+    if (pdgcode_str) {
+      int64_t pdgcode64;
+      if (!mcpl_str2int(pdgcode_str, 0, &pdgcode64) || pdgcode64<INT32_MIN || pdgcode64>INT32_MAX || !pdgcode64)
+        return mcpl_tool_usage(argv,"Must specify non-zero 32bit integer as argument to -p.");
+      pdgcode_select = (int32_t)pdgcode64;
+    }
+
+    if (opt_num_skip>0)
+      mcpl_seek(fi,(uint64_t)opt_num_skip);
+
+    uint64_t left = opt_num_limit>0 ? (uint64_t)opt_num_limit : UINT64_MAX;
+    uint64_t added = 0;
+    const mcpl_particle_t* particle;
+    while ( left-- && ( particle = mcpl_read(fi) ) ) {
+      if (pdgcode_select && pdgcode_select!= particle->pdgcode)
+        continue;
+      mcpl_add_particle(fo,particle);
+      ++added;
+    }
+
+    char *fo_filename = (char*)malloc(strlen(mcpl_outfile_filename(fo))+4);
+    fo_filename[0] = '\0';
+    strcat(fo_filename,mcpl_outfile_filename(fo));
+    if (mcpl_closeandgzip_outfile_rc(fo))
+      strcat(fo_filename,".gz");
+    mcpl_close_file(fi);
+
+    printf("MCPL: Succesfully extracted %" PRIu64 " / %" PRIu64 " particles from %s into %s\n",
+           added,fi_nparticles,filename1,fo_filename);
+    free(fo_filename);
+    return 0;
+  }
+
   if (filename2)
     return mcpl_tool_usage(argv,"Too many arguments.");
 
diff --git a/src/mcpl/mcpl.h b/src/mcpl/mcpl.h
index e52659fc1718f536d30faefc781b606b6d9c7bc9..1621c793439716fb6b8cde978a86c13464140034 100644
--- a/src/mcpl/mcpl.h
+++ b/src/mcpl/mcpl.h
@@ -11,7 +11,7 @@
 /*  particle state information, for interchanging and reshooting events between    */
 /*  various Monte Carlo simulation applications.                                   */
 /*                                                                                 */
-/*  Refer to the top of mcpl.c for details regarding how to build.                 */
+/*  Find more information and updates at https://mctools.github.io/mcpl/           */
 /*                                                                                 */
 /*  This file can be freely used as per the terms in the LICENSE file.             */
 /*                                                                                 */
@@ -20,9 +20,9 @@
 /***********************************************************************************/
 
 #define MCPL_VERSION_MAJOR 0
-#define MCPL_VERSION_MINOR 7
+#define MCPL_VERSION_MINOR 99
 #define MCPL_VERSION_PATCH 0
-#define MCPL_VERSION     700 /* (10000*MAJOR+100*MINOR+PATCH)   */
+#define MCPL_VERSION    9900 /* (10000*MAJOR+100*MINOR+PATCH)   */
 #define MCPL_FORMATVERSION 2 /* Format version of written files */
 
 #ifdef __cplusplus
diff --git a/src_fat/mcpl2ssw_app_fat.c b/src_fat/mcpl2ssw_app_fat.c
index 3c78838edb83e4d6c9ab87a7f729a2edbd4f3b41..6948af4a53ed7f177b8989374509a0d3e0b79cdc 100644
--- a/src_fat/mcpl2ssw_app_fat.c
+++ b/src_fat/mcpl2ssw_app_fat.c
@@ -60,7 +60,7 @@
 /*  particle state information, for interchanging and reshooting events between    */
 /*  various Monte Carlo simulation applications.                                   */
 /*                                                                                 */
-/*  Refer to the top of mcpl.c for details regarding how to build.                 */
+/*  Find more information and updates at https://mctools.github.io/mcpl/           */
 /*                                                                                 */
 /*  This file can be freely used as per the terms in the LICENSE file.             */
 /*                                                                                 */
@@ -69,9 +69,9 @@
 /***********************************************************************************/
 
 #define MCPL_VERSION_MAJOR 0
-#define MCPL_VERSION_MINOR 7
+#define MCPL_VERSION_MINOR 99
 #define MCPL_VERSION_PATCH 0
-#define MCPL_VERSION     700 /* (10000*MAJOR+100*MINOR+PATCH)   */
+#define MCPL_VERSION    9900 /* (10000*MAJOR+100*MINOR+PATCH)   */
 #define MCPL_FORMATVERSION 2 /* Format version of written files */
 
 #ifdef __cplusplus
@@ -329,6 +329,8 @@ int mcpl2ssw_app(int argc,char** argv);
 //                                                                                 //
 //  This file can be freely used as per the terms in the LICENSE file.             //
 //                                                                                 //
+//  Find more information and updates at https://mctools.github.io/mcpl/           //
+//                                                                                 //
 //  Written by Thomas Kittelmann, 2015-2016.                                       //
 //                                                                                 //
 /////////////////////////////////////////////////////////////////////////////////////
@@ -336,14 +338,6 @@ int mcpl2ssw_app(int argc,char** argv);
 
 //////
 //
-// TODO:
-//  * Implement --ignore flag for --merge.
-//
-// Planned features delayed for next release (not implemented yet):
-//  * Don't require code to calloc and keep track of their own mcpl_particle_t instance.
-//  * mcpl_gzip_file and mcpl_closeandgzip_outfile must return status indicating
-//    success or not (to know if .mcpl or .mcpl.gz file is the result).
-//
 //Possible future developments:
 //
 //  1) Support for particle groups ("events"). The file writing interface would
@@ -389,7 +383,7 @@ int mcpl2ssw_app(int argc,char** argv);
 // 8) Consider writing .mcpl.gz files directly (through a large buffer
 //    presumably). Or to have compressed blocks internally.
 //
-// 9) Should use unsigned char* rather than char* for buffers.
+// 9) Should use unsigned char* rather than char* for buffers?
 //
 //////
 
@@ -4159,11 +4153,12 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("Usage:\n");
   printf("  %s [dump-options] FILE\n",progname);
   printf("  %s --merge [merge-options] FILE1 FILE2\n",progname);
+  printf("  %s --extract [extract-options] FILE1 FILE2\n",progname);
   printf("  %s --repair FILE\n",progname);
   printf("  %s --version\n",progname);
   printf("  %s --help\n",progname);
   printf("\n");
-  printf("Dump Options:\n");
+  printf("Dump options:\n");
   printf("  By default include the info in the FILE header plus the first ten contained\n");
   printf("  particles. Modify with the following options:\n");
   assert(MCPLIMP_TOOL_DEFAULT_NLIMIT==10);
@@ -4174,13 +4169,17 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("  -sN             : Skip past the first N particles in the file (default %i).\n",MCPLIMP_TOOL_DEFAULT_NSKIP);
   printf("  -bKEY           : Dump binary blob stored under KEY to standard output.\n");
   printf("\n");
-  printf("Merge Options:\n");
+  printf("Merge options:\n");
   printf("  -m, --merge FILE1 FILE2\n");
   printf("                    Appends the particle contents in FILE2 to the end of FILE1.\n");
-  printf("                    Note that this will fail unless FILE1 and FILE2 have iden-\n");
-  printf("                    tical headers (but see option --ignore below).\n");
-  printf("  -i, --ignore      Ignore comments and binary blobs in FILE2. This allows some\n");
-  printf("                    otherwise forbidden merges, but some info might get lost.\n");
+  printf("                    Note that this will fail unless FILE1 and FILE2 have compa-\n");
+  printf("                    tible headers.\n");
+  printf("\n");
+  printf("Extract options:\n");
+  printf("  -e, --extract FILE1 FILE2\n");
+  printf("                    Extracts particles from FILE1 into a new FILE2.\n");
+  printf("  -lN, -sN          Select range of particles in FILE1 (as above).\n");
+  printf("  -pPDGCODE         select particles of type given by PDGCODE.\n");
   printf("\n");
   printf("Other options:\n");
   printf("  -r, --repair FILE\n");
@@ -4192,16 +4191,45 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   return 0;
 }
 
+int mcpl_str2int(const char* str, size_t len, int64_t* res)
+{
+  //portable 64bit str2int with error checking.
+  *res = 0;
+  if (!len)
+    len=strlen(str);
+  if (!len)
+    return 0;
+  int sign = 1;
+  if (str[0]=='-') {
+    sign = -1;
+    len -= 1;
+    str += 1;
+  }
+  int64_t tmp = 0;
+  for (size_t i=0; i<len; ++i) {
+    if (str[i]<'0'||str[i]>'9') {
+      return 0;
+    }
+    tmp *= 10;
+    tmp += str[i] - '0';
+  }
+  if (tmp > INT64_MAX)
+    return 0;
+  *res = sign * tmp;
+  return 1;
+}
+
 int mcpl_tool(int argc,char** argv) {
   const char * filename1 = 0;
   const char * filename2 = 0;
   const char * blobkey = 0;
+  const char * pdgcode_str = 0;
   int opt_justhead = 0;
   int opt_nohead = 0;
   int64_t opt_num_limit = -1;
   int64_t opt_num_skip = -1;
   int opt_merge = 0;
-  int opt_ignore = 0;
+  int opt_extract = 0;
   int opt_repair = 0;
   int opt_version = 0;
 
@@ -4229,18 +4257,26 @@ int mcpl_tool(int argc,char** argv) {
           blobkey = a+j+1;
           break;
         }
+        if (a[j]=='p') {
+          if (pdgcode_str)
+            return mcpl_tool_usage(argv,"-p specified more than once");
+          if (j+1==n)
+            return mcpl_tool_usage(argv,"Missing argument for -p");
+          pdgcode_str = a+j+1;
+          break;
+        }
+
         switch(a[j]) {
           case 'h': return mcpl_tool_usage(argv,0);
           case 'j': opt_justhead = 1; break;
           case 'n': opt_nohead = 1; break;
           case 'm': opt_merge = 1; break;
-          case 'i': opt_ignore = 1; break;
+          case 'e': opt_extract = 1; break;
           case 'r': opt_repair = 1; break;
           case 'v': opt_version = 1; break;
           case 'l': consume_digit = &opt_num_limit; break;
           case 's': consume_digit = &opt_num_skip; break;
           default:
-            printf("%c\n",a[j]);
             return mcpl_tool_usage(argv,"Unrecognised option");
         }
         if (consume_digit) {
@@ -4256,7 +4292,7 @@ int mcpl_tool(int argc,char** argv) {
       const char * lo_justhead = "justhead";
       const char * lo_nohead = "nohead";
       const char * lo_merge = "merge";
-      const char * lo_ignore = "ignore";
+      const char * lo_extract = "extract";
       const char * lo_repair = "repair";
       const char * lo_version = "version";
       //Use strstr instead of "strcmp(a,"--help")==0" to support shortened
@@ -4265,7 +4301,7 @@ int mcpl_tool(int argc,char** argv) {
       else if (strstr(lo_justhead,a)==lo_justhead) opt_justhead = 1;
       else if (strstr(lo_nohead,a)==lo_nohead) opt_nohead = 1;
       else if (strstr(lo_merge,a)==lo_merge) opt_merge = 1;
-      else if (strstr(lo_ignore,a)==lo_ignore) opt_ignore = 1;
+      else if (strstr(lo_extract,a)==lo_extract) opt_extract = 1;
       else if (strstr(lo_repair,a)==lo_repair) opt_repair = 1;
       else if (strstr(lo_version,a)==lo_version) opt_version = 1;
       else return mcpl_tool_usage(argv,"Unrecognised option");
@@ -4279,10 +4315,17 @@ int mcpl_tool(int argc,char** argv) {
       return mcpl_tool_usage(argv,"Bad arguments");
     }
   }
-  int number_dumpopts = (opt_justhead + opt_nohead + (opt_num_limit!=-1) + (opt_num_skip!=-1) + (blobkey!=0));
+
+  if ( opt_extract==0 && pdgcode_str )
+    return mcpl_tool_usage(argv,"-p can only be used with --extract.");
+
+  int number_dumpopts = (opt_justhead + opt_nohead + (blobkey!=0));
+  if (opt_extract==0)
+    number_dumpopts += (opt_num_limit!=-1) + (opt_num_skip!=-1);
   int any_dumpopts = number_dumpopts != 0;
-  int any_mergeopts = (opt_merge + opt_ignore)!=0;
-  if (any_dumpopts+any_mergeopts+opt_repair+opt_version>1)
+  int any_extractopts = (opt_extract!=0||pdgcode_str!=0);
+  int any_mergeopts = (opt_merge!=0);
+  if (any_dumpopts+any_mergeopts+any_extractopts+opt_repair+opt_version>1)
     return mcpl_tool_usage(argv,"Conflicting options specified.");
 
   if (blobkey&&(number_dumpopts>1))
@@ -4295,14 +4338,9 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
-  if (opt_ignore&&!opt_merge)
-    return mcpl_tool_usage(argv,"Use --ignore only with --merge.");
-
   if (opt_merge) {
     if (!filename2)
       return mcpl_tool_usage(argv,"Must specify two input files with --merge.");
-    if (opt_ignore)
-      return mcpl_tool_usage(argv,"--ignore is not implemented yet.");
 
     if (!mcpl_can_merge(filename1,filename2))
       return mcpl_tool_usage(argv,"Requested files are incompatible for merge as they have different header info.");
@@ -4311,6 +4349,53 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
+  if (opt_extract) {
+    if (!filename2)
+      return mcpl_tool_usage(argv,"Must specify both input and output files with --extract.");
+
+    mcpl_file_t fi = mcpl_open_file(filename1);
+    mcpl_outfile_t fo = mcpl_create_outfile(filename2);
+    mcpl_transfer_metadata(fi, fo);
+    uint64_t fi_nparticles = mcpl_hdr_nparticles(fi);
+
+    char comment[1024];
+    sprintf(comment, "mcpltool: extracted particles from file with %" PRIu64 " particles",fi_nparticles);
+    mcpl_hdr_add_comment(fo,comment);
+
+    int32_t pdgcode_select = 0;
+    if (pdgcode_str) {
+      int64_t pdgcode64;
+      if (!mcpl_str2int(pdgcode_str, 0, &pdgcode64) || pdgcode64<INT32_MIN || pdgcode64>INT32_MAX || !pdgcode64)
+        return mcpl_tool_usage(argv,"Must specify non-zero 32bit integer as argument to -p.");
+      pdgcode_select = (int32_t)pdgcode64;
+    }
+
+    if (opt_num_skip>0)
+      mcpl_seek(fi,(uint64_t)opt_num_skip);
+
+    uint64_t left = opt_num_limit>0 ? (uint64_t)opt_num_limit : UINT64_MAX;
+    uint64_t added = 0;
+    const mcpl_particle_t* particle;
+    while ( left-- && ( particle = mcpl_read(fi) ) ) {
+      if (pdgcode_select && pdgcode_select!= particle->pdgcode)
+        continue;
+      mcpl_add_particle(fo,particle);
+      ++added;
+    }
+
+    char *fo_filename = (char*)malloc(strlen(mcpl_outfile_filename(fo))+4);
+    fo_filename[0] = '\0';
+    strcat(fo_filename,mcpl_outfile_filename(fo));
+    if (mcpl_closeandgzip_outfile_rc(fo))
+      strcat(fo_filename,".gz");
+    mcpl_close_file(fi);
+
+    printf("MCPL: Succesfully extracted %" PRIu64 " / %" PRIu64 " particles from %s into %s\n",
+           added,fi_nparticles,filename1,fo_filename);
+    free(fo_filename);
+    return 0;
+  }
+
   if (filename2)
     return mcpl_tool_usage(argv,"Too many arguments.");
 
diff --git a/src_fat/mcpl_fat.c b/src_fat/mcpl_fat.c
index 3b5bf7b2bfa33a870b4c4411d51533c3ddb1de19..3d29a1e30ae8f6c4a52b8059121e5821fb3a8cef 100644
--- a/src_fat/mcpl_fat.c
+++ b/src_fat/mcpl_fat.c
@@ -51,6 +51,8 @@
 //                                                                                 //
 //  This file can be freely used as per the terms in the LICENSE file.             //
 //                                                                                 //
+//  Find more information and updates at https://mctools.github.io/mcpl/           //
+//                                                                                 //
 //  Written by Thomas Kittelmann, 2015-2016.                                       //
 //                                                                                 //
 /////////////////////////////////////////////////////////////////////////////////////
@@ -58,14 +60,6 @@
 
 //////
 //
-// TODO:
-//  * Implement --ignore flag for --merge.
-//
-// Planned features delayed for next release (not implemented yet):
-//  * Don't require code to calloc and keep track of their own mcpl_particle_t instance.
-//  * mcpl_gzip_file and mcpl_closeandgzip_outfile must return status indicating
-//    success or not (to know if .mcpl or .mcpl.gz file is the result).
-//
 //Possible future developments:
 //
 //  1) Support for particle groups ("events"). The file writing interface would
@@ -111,7 +105,7 @@
 // 8) Consider writing .mcpl.gz files directly (through a large buffer
 //    presumably). Or to have compressed blocks internally.
 //
-// 9) Should use unsigned char* rather than char* for buffers.
+// 9) Should use unsigned char* rather than char* for buffers?
 //
 //////
 
@@ -3882,11 +3876,12 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("Usage:\n");
   printf("  %s [dump-options] FILE\n",progname);
   printf("  %s --merge [merge-options] FILE1 FILE2\n",progname);
+  printf("  %s --extract [extract-options] FILE1 FILE2\n",progname);
   printf("  %s --repair FILE\n",progname);
   printf("  %s --version\n",progname);
   printf("  %s --help\n",progname);
   printf("\n");
-  printf("Dump Options:\n");
+  printf("Dump options:\n");
   printf("  By default include the info in the FILE header plus the first ten contained\n");
   printf("  particles. Modify with the following options:\n");
   assert(MCPLIMP_TOOL_DEFAULT_NLIMIT==10);
@@ -3897,13 +3892,17 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("  -sN             : Skip past the first N particles in the file (default %i).\n",MCPLIMP_TOOL_DEFAULT_NSKIP);
   printf("  -bKEY           : Dump binary blob stored under KEY to standard output.\n");
   printf("\n");
-  printf("Merge Options:\n");
+  printf("Merge options:\n");
   printf("  -m, --merge FILE1 FILE2\n");
   printf("                    Appends the particle contents in FILE2 to the end of FILE1.\n");
-  printf("                    Note that this will fail unless FILE1 and FILE2 have iden-\n");
-  printf("                    tical headers (but see option --ignore below).\n");
-  printf("  -i, --ignore      Ignore comments and binary blobs in FILE2. This allows some\n");
-  printf("                    otherwise forbidden merges, but some info might get lost.\n");
+  printf("                    Note that this will fail unless FILE1 and FILE2 have compa-\n");
+  printf("                    tible headers.\n");
+  printf("\n");
+  printf("Extract options:\n");
+  printf("  -e, --extract FILE1 FILE2\n");
+  printf("                    Extracts particles from FILE1 into a new FILE2.\n");
+  printf("  -lN, -sN          Select range of particles in FILE1 (as above).\n");
+  printf("  -pPDGCODE         select particles of type given by PDGCODE.\n");
   printf("\n");
   printf("Other options:\n");
   printf("  -r, --repair FILE\n");
@@ -3915,16 +3914,45 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   return 0;
 }
 
+int mcpl_str2int(const char* str, size_t len, int64_t* res)
+{
+  //portable 64bit str2int with error checking.
+  *res = 0;
+  if (!len)
+    len=strlen(str);
+  if (!len)
+    return 0;
+  int sign = 1;
+  if (str[0]=='-') {
+    sign = -1;
+    len -= 1;
+    str += 1;
+  }
+  int64_t tmp = 0;
+  for (size_t i=0; i<len; ++i) {
+    if (str[i]<'0'||str[i]>'9') {
+      return 0;
+    }
+    tmp *= 10;
+    tmp += str[i] - '0';
+  }
+  if (tmp > INT64_MAX)
+    return 0;
+  *res = sign * tmp;
+  return 1;
+}
+
 int mcpl_tool(int argc,char** argv) {
   const char * filename1 = 0;
   const char * filename2 = 0;
   const char * blobkey = 0;
+  const char * pdgcode_str = 0;
   int opt_justhead = 0;
   int opt_nohead = 0;
   int64_t opt_num_limit = -1;
   int64_t opt_num_skip = -1;
   int opt_merge = 0;
-  int opt_ignore = 0;
+  int opt_extract = 0;
   int opt_repair = 0;
   int opt_version = 0;
 
@@ -3952,18 +3980,26 @@ int mcpl_tool(int argc,char** argv) {
           blobkey = a+j+1;
           break;
         }
+        if (a[j]=='p') {
+          if (pdgcode_str)
+            return mcpl_tool_usage(argv,"-p specified more than once");
+          if (j+1==n)
+            return mcpl_tool_usage(argv,"Missing argument for -p");
+          pdgcode_str = a+j+1;
+          break;
+        }
+
         switch(a[j]) {
           case 'h': return mcpl_tool_usage(argv,0);
           case 'j': opt_justhead = 1; break;
           case 'n': opt_nohead = 1; break;
           case 'm': opt_merge = 1; break;
-          case 'i': opt_ignore = 1; break;
+          case 'e': opt_extract = 1; break;
           case 'r': opt_repair = 1; break;
           case 'v': opt_version = 1; break;
           case 'l': consume_digit = &opt_num_limit; break;
           case 's': consume_digit = &opt_num_skip; break;
           default:
-            printf("%c\n",a[j]);
             return mcpl_tool_usage(argv,"Unrecognised option");
         }
         if (consume_digit) {
@@ -3979,7 +4015,7 @@ int mcpl_tool(int argc,char** argv) {
       const char * lo_justhead = "justhead";
       const char * lo_nohead = "nohead";
       const char * lo_merge = "merge";
-      const char * lo_ignore = "ignore";
+      const char * lo_extract = "extract";
       const char * lo_repair = "repair";
       const char * lo_version = "version";
       //Use strstr instead of "strcmp(a,"--help")==0" to support shortened
@@ -3988,7 +4024,7 @@ int mcpl_tool(int argc,char** argv) {
       else if (strstr(lo_justhead,a)==lo_justhead) opt_justhead = 1;
       else if (strstr(lo_nohead,a)==lo_nohead) opt_nohead = 1;
       else if (strstr(lo_merge,a)==lo_merge) opt_merge = 1;
-      else if (strstr(lo_ignore,a)==lo_ignore) opt_ignore = 1;
+      else if (strstr(lo_extract,a)==lo_extract) opt_extract = 1;
       else if (strstr(lo_repair,a)==lo_repair) opt_repair = 1;
       else if (strstr(lo_version,a)==lo_version) opt_version = 1;
       else return mcpl_tool_usage(argv,"Unrecognised option");
@@ -4002,10 +4038,17 @@ int mcpl_tool(int argc,char** argv) {
       return mcpl_tool_usage(argv,"Bad arguments");
     }
   }
-  int number_dumpopts = (opt_justhead + opt_nohead + (opt_num_limit!=-1) + (opt_num_skip!=-1) + (blobkey!=0));
+
+  if ( opt_extract==0 && pdgcode_str )
+    return mcpl_tool_usage(argv,"-p can only be used with --extract.");
+
+  int number_dumpopts = (opt_justhead + opt_nohead + (blobkey!=0));
+  if (opt_extract==0)
+    number_dumpopts += (opt_num_limit!=-1) + (opt_num_skip!=-1);
   int any_dumpopts = number_dumpopts != 0;
-  int any_mergeopts = (opt_merge + opt_ignore)!=0;
-  if (any_dumpopts+any_mergeopts+opt_repair+opt_version>1)
+  int any_extractopts = (opt_extract!=0||pdgcode_str!=0);
+  int any_mergeopts = (opt_merge!=0);
+  if (any_dumpopts+any_mergeopts+any_extractopts+opt_repair+opt_version>1)
     return mcpl_tool_usage(argv,"Conflicting options specified.");
 
   if (blobkey&&(number_dumpopts>1))
@@ -4018,14 +4061,9 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
-  if (opt_ignore&&!opt_merge)
-    return mcpl_tool_usage(argv,"Use --ignore only with --merge.");
-
   if (opt_merge) {
     if (!filename2)
       return mcpl_tool_usage(argv,"Must specify two input files with --merge.");
-    if (opt_ignore)
-      return mcpl_tool_usage(argv,"--ignore is not implemented yet.");
 
     if (!mcpl_can_merge(filename1,filename2))
       return mcpl_tool_usage(argv,"Requested files are incompatible for merge as they have different header info.");
@@ -4034,6 +4072,53 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
+  if (opt_extract) {
+    if (!filename2)
+      return mcpl_tool_usage(argv,"Must specify both input and output files with --extract.");
+
+    mcpl_file_t fi = mcpl_open_file(filename1);
+    mcpl_outfile_t fo = mcpl_create_outfile(filename2);
+    mcpl_transfer_metadata(fi, fo);
+    uint64_t fi_nparticles = mcpl_hdr_nparticles(fi);
+
+    char comment[1024];
+    sprintf(comment, "mcpltool: extracted particles from file with %" PRIu64 " particles",fi_nparticles);
+    mcpl_hdr_add_comment(fo,comment);
+
+    int32_t pdgcode_select = 0;
+    if (pdgcode_str) {
+      int64_t pdgcode64;
+      if (!mcpl_str2int(pdgcode_str, 0, &pdgcode64) || pdgcode64<INT32_MIN || pdgcode64>INT32_MAX || !pdgcode64)
+        return mcpl_tool_usage(argv,"Must specify non-zero 32bit integer as argument to -p.");
+      pdgcode_select = (int32_t)pdgcode64;
+    }
+
+    if (opt_num_skip>0)
+      mcpl_seek(fi,(uint64_t)opt_num_skip);
+
+    uint64_t left = opt_num_limit>0 ? (uint64_t)opt_num_limit : UINT64_MAX;
+    uint64_t added = 0;
+    const mcpl_particle_t* particle;
+    while ( left-- && ( particle = mcpl_read(fi) ) ) {
+      if (pdgcode_select && pdgcode_select!= particle->pdgcode)
+        continue;
+      mcpl_add_particle(fo,particle);
+      ++added;
+    }
+
+    char *fo_filename = (char*)malloc(strlen(mcpl_outfile_filename(fo))+4);
+    fo_filename[0] = '\0';
+    strcat(fo_filename,mcpl_outfile_filename(fo));
+    if (mcpl_closeandgzip_outfile_rc(fo))
+      strcat(fo_filename,".gz");
+    mcpl_close_file(fi);
+
+    printf("MCPL: Succesfully extracted %" PRIu64 " / %" PRIu64 " particles from %s into %s\n",
+           added,fi_nparticles,filename1,fo_filename);
+    free(fo_filename);
+    return 0;
+  }
+
   if (filename2)
     return mcpl_tool_usage(argv,"Too many arguments.");
 
diff --git a/src_fat/mcpltool_app_fat.c b/src_fat/mcpltool_app_fat.c
index 1724748576f9925bc90fd00d2368e2f3ffbc732f..59c43a688b6bd575f85fe905034326632947e7cf 100644
--- a/src_fat/mcpltool_app_fat.c
+++ b/src_fat/mcpltool_app_fat.c
@@ -76,6 +76,8 @@
 //                                                                                 //
 //  This file can be freely used as per the terms in the LICENSE file.             //
 //                                                                                 //
+//  Find more information and updates at https://mctools.github.io/mcpl/           //
+//                                                                                 //
 //  Written by Thomas Kittelmann, 2015-2016.                                       //
 //                                                                                 //
 /////////////////////////////////////////////////////////////////////////////////////
@@ -83,14 +85,6 @@
 
 //////
 //
-// TODO:
-//  * Implement --ignore flag for --merge.
-//
-// Planned features delayed for next release (not implemented yet):
-//  * Don't require code to calloc and keep track of their own mcpl_particle_t instance.
-//  * mcpl_gzip_file and mcpl_closeandgzip_outfile must return status indicating
-//    success or not (to know if .mcpl or .mcpl.gz file is the result).
-//
 //Possible future developments:
 //
 //  1) Support for particle groups ("events"). The file writing interface would
@@ -136,7 +130,7 @@
 // 8) Consider writing .mcpl.gz files directly (through a large buffer
 //    presumably). Or to have compressed blocks internally.
 //
-// 9) Should use unsigned char* rather than char* for buffers.
+// 9) Should use unsigned char* rather than char* for buffers?
 //
 //////
 
@@ -174,7 +168,7 @@
 /*  particle state information, for interchanging and reshooting events between    */
 /*  various Monte Carlo simulation applications.                                   */
 /*                                                                                 */
-/*  Refer to the top of mcpl.c for details regarding how to build.                 */
+/*  Find more information and updates at https://mctools.github.io/mcpl/           */
 /*                                                                                 */
 /*  This file can be freely used as per the terms in the LICENSE file.             */
 /*                                                                                 */
@@ -183,9 +177,9 @@
 /***********************************************************************************/
 
 #define MCPL_VERSION_MAJOR 0
-#define MCPL_VERSION_MINOR 7
+#define MCPL_VERSION_MINOR 99
 #define MCPL_VERSION_PATCH 0
-#define MCPL_VERSION     700 /* (10000*MAJOR+100*MINOR+PATCH)   */
+#define MCPL_VERSION    9900 /* (10000*MAJOR+100*MINOR+PATCH)   */
 #define MCPL_FORMATVERSION 2 /* Format version of written files */
 
 #ifdef __cplusplus
@@ -4085,11 +4079,12 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("Usage:\n");
   printf("  %s [dump-options] FILE\n",progname);
   printf("  %s --merge [merge-options] FILE1 FILE2\n",progname);
+  printf("  %s --extract [extract-options] FILE1 FILE2\n",progname);
   printf("  %s --repair FILE\n",progname);
   printf("  %s --version\n",progname);
   printf("  %s --help\n",progname);
   printf("\n");
-  printf("Dump Options:\n");
+  printf("Dump options:\n");
   printf("  By default include the info in the FILE header plus the first ten contained\n");
   printf("  particles. Modify with the following options:\n");
   assert(MCPLIMP_TOOL_DEFAULT_NLIMIT==10);
@@ -4100,13 +4095,17 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("  -sN             : Skip past the first N particles in the file (default %i).\n",MCPLIMP_TOOL_DEFAULT_NSKIP);
   printf("  -bKEY           : Dump binary blob stored under KEY to standard output.\n");
   printf("\n");
-  printf("Merge Options:\n");
+  printf("Merge options:\n");
   printf("  -m, --merge FILE1 FILE2\n");
   printf("                    Appends the particle contents in FILE2 to the end of FILE1.\n");
-  printf("                    Note that this will fail unless FILE1 and FILE2 have iden-\n");
-  printf("                    tical headers (but see option --ignore below).\n");
-  printf("  -i, --ignore      Ignore comments and binary blobs in FILE2. This allows some\n");
-  printf("                    otherwise forbidden merges, but some info might get lost.\n");
+  printf("                    Note that this will fail unless FILE1 and FILE2 have compa-\n");
+  printf("                    tible headers.\n");
+  printf("\n");
+  printf("Extract options:\n");
+  printf("  -e, --extract FILE1 FILE2\n");
+  printf("                    Extracts particles from FILE1 into a new FILE2.\n");
+  printf("  -lN, -sN          Select range of particles in FILE1 (as above).\n");
+  printf("  -pPDGCODE         select particles of type given by PDGCODE.\n");
   printf("\n");
   printf("Other options:\n");
   printf("  -r, --repair FILE\n");
@@ -4118,16 +4117,45 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   return 0;
 }
 
+int mcpl_str2int(const char* str, size_t len, int64_t* res)
+{
+  //portable 64bit str2int with error checking.
+  *res = 0;
+  if (!len)
+    len=strlen(str);
+  if (!len)
+    return 0;
+  int sign = 1;
+  if (str[0]=='-') {
+    sign = -1;
+    len -= 1;
+    str += 1;
+  }
+  int64_t tmp = 0;
+  for (size_t i=0; i<len; ++i) {
+    if (str[i]<'0'||str[i]>'9') {
+      return 0;
+    }
+    tmp *= 10;
+    tmp += str[i] - '0';
+  }
+  if (tmp > INT64_MAX)
+    return 0;
+  *res = sign * tmp;
+  return 1;
+}
+
 int mcpl_tool(int argc,char** argv) {
   const char * filename1 = 0;
   const char * filename2 = 0;
   const char * blobkey = 0;
+  const char * pdgcode_str = 0;
   int opt_justhead = 0;
   int opt_nohead = 0;
   int64_t opt_num_limit = -1;
   int64_t opt_num_skip = -1;
   int opt_merge = 0;
-  int opt_ignore = 0;
+  int opt_extract = 0;
   int opt_repair = 0;
   int opt_version = 0;
 
@@ -4155,18 +4183,26 @@ int mcpl_tool(int argc,char** argv) {
           blobkey = a+j+1;
           break;
         }
+        if (a[j]=='p') {
+          if (pdgcode_str)
+            return mcpl_tool_usage(argv,"-p specified more than once");
+          if (j+1==n)
+            return mcpl_tool_usage(argv,"Missing argument for -p");
+          pdgcode_str = a+j+1;
+          break;
+        }
+
         switch(a[j]) {
           case 'h': return mcpl_tool_usage(argv,0);
           case 'j': opt_justhead = 1; break;
           case 'n': opt_nohead = 1; break;
           case 'm': opt_merge = 1; break;
-          case 'i': opt_ignore = 1; break;
+          case 'e': opt_extract = 1; break;
           case 'r': opt_repair = 1; break;
           case 'v': opt_version = 1; break;
           case 'l': consume_digit = &opt_num_limit; break;
           case 's': consume_digit = &opt_num_skip; break;
           default:
-            printf("%c\n",a[j]);
             return mcpl_tool_usage(argv,"Unrecognised option");
         }
         if (consume_digit) {
@@ -4182,7 +4218,7 @@ int mcpl_tool(int argc,char** argv) {
       const char * lo_justhead = "justhead";
       const char * lo_nohead = "nohead";
       const char * lo_merge = "merge";
-      const char * lo_ignore = "ignore";
+      const char * lo_extract = "extract";
       const char * lo_repair = "repair";
       const char * lo_version = "version";
       //Use strstr instead of "strcmp(a,"--help")==0" to support shortened
@@ -4191,7 +4227,7 @@ int mcpl_tool(int argc,char** argv) {
       else if (strstr(lo_justhead,a)==lo_justhead) opt_justhead = 1;
       else if (strstr(lo_nohead,a)==lo_nohead) opt_nohead = 1;
       else if (strstr(lo_merge,a)==lo_merge) opt_merge = 1;
-      else if (strstr(lo_ignore,a)==lo_ignore) opt_ignore = 1;
+      else if (strstr(lo_extract,a)==lo_extract) opt_extract = 1;
       else if (strstr(lo_repair,a)==lo_repair) opt_repair = 1;
       else if (strstr(lo_version,a)==lo_version) opt_version = 1;
       else return mcpl_tool_usage(argv,"Unrecognised option");
@@ -4205,10 +4241,17 @@ int mcpl_tool(int argc,char** argv) {
       return mcpl_tool_usage(argv,"Bad arguments");
     }
   }
-  int number_dumpopts = (opt_justhead + opt_nohead + (opt_num_limit!=-1) + (opt_num_skip!=-1) + (blobkey!=0));
+
+  if ( opt_extract==0 && pdgcode_str )
+    return mcpl_tool_usage(argv,"-p can only be used with --extract.");
+
+  int number_dumpopts = (opt_justhead + opt_nohead + (blobkey!=0));
+  if (opt_extract==0)
+    number_dumpopts += (opt_num_limit!=-1) + (opt_num_skip!=-1);
   int any_dumpopts = number_dumpopts != 0;
-  int any_mergeopts = (opt_merge + opt_ignore)!=0;
-  if (any_dumpopts+any_mergeopts+opt_repair+opt_version>1)
+  int any_extractopts = (opt_extract!=0||pdgcode_str!=0);
+  int any_mergeopts = (opt_merge!=0);
+  if (any_dumpopts+any_mergeopts+any_extractopts+opt_repair+opt_version>1)
     return mcpl_tool_usage(argv,"Conflicting options specified.");
 
   if (blobkey&&(number_dumpopts>1))
@@ -4221,14 +4264,9 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
-  if (opt_ignore&&!opt_merge)
-    return mcpl_tool_usage(argv,"Use --ignore only with --merge.");
-
   if (opt_merge) {
     if (!filename2)
       return mcpl_tool_usage(argv,"Must specify two input files with --merge.");
-    if (opt_ignore)
-      return mcpl_tool_usage(argv,"--ignore is not implemented yet.");
 
     if (!mcpl_can_merge(filename1,filename2))
       return mcpl_tool_usage(argv,"Requested files are incompatible for merge as they have different header info.");
@@ -4237,6 +4275,53 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
+  if (opt_extract) {
+    if (!filename2)
+      return mcpl_tool_usage(argv,"Must specify both input and output files with --extract.");
+
+    mcpl_file_t fi = mcpl_open_file(filename1);
+    mcpl_outfile_t fo = mcpl_create_outfile(filename2);
+    mcpl_transfer_metadata(fi, fo);
+    uint64_t fi_nparticles = mcpl_hdr_nparticles(fi);
+
+    char comment[1024];
+    sprintf(comment, "mcpltool: extracted particles from file with %" PRIu64 " particles",fi_nparticles);
+    mcpl_hdr_add_comment(fo,comment);
+
+    int32_t pdgcode_select = 0;
+    if (pdgcode_str) {
+      int64_t pdgcode64;
+      if (!mcpl_str2int(pdgcode_str, 0, &pdgcode64) || pdgcode64<INT32_MIN || pdgcode64>INT32_MAX || !pdgcode64)
+        return mcpl_tool_usage(argv,"Must specify non-zero 32bit integer as argument to -p.");
+      pdgcode_select = (int32_t)pdgcode64;
+    }
+
+    if (opt_num_skip>0)
+      mcpl_seek(fi,(uint64_t)opt_num_skip);
+
+    uint64_t left = opt_num_limit>0 ? (uint64_t)opt_num_limit : UINT64_MAX;
+    uint64_t added = 0;
+    const mcpl_particle_t* particle;
+    while ( left-- && ( particle = mcpl_read(fi) ) ) {
+      if (pdgcode_select && pdgcode_select!= particle->pdgcode)
+        continue;
+      mcpl_add_particle(fo,particle);
+      ++added;
+    }
+
+    char *fo_filename = (char*)malloc(strlen(mcpl_outfile_filename(fo))+4);
+    fo_filename[0] = '\0';
+    strcat(fo_filename,mcpl_outfile_filename(fo));
+    if (mcpl_closeandgzip_outfile_rc(fo))
+      strcat(fo_filename,".gz");
+    mcpl_close_file(fi);
+
+    printf("MCPL: Succesfully extracted %" PRIu64 " / %" PRIu64 " particles from %s into %s\n",
+           added,fi_nparticles,filename1,fo_filename);
+    free(fo_filename);
+    return 0;
+  }
+
   if (filename2)
     return mcpl_tool_usage(argv,"Too many arguments.");
 
diff --git a/src_fat/ssw2mcpl_app_fat.c b/src_fat/ssw2mcpl_app_fat.c
index 85cfd28c264e20d03b52c6f9285e3cf744f6e947..18e9b7d7c2fe61727a621b2635aa325a17ef38af 100644
--- a/src_fat/ssw2mcpl_app_fat.c
+++ b/src_fat/ssw2mcpl_app_fat.c
@@ -60,7 +60,7 @@
 /*  particle state information, for interchanging and reshooting events between    */
 /*  various Monte Carlo simulation applications.                                   */
 /*                                                                                 */
-/*  Refer to the top of mcpl.c for details regarding how to build.                 */
+/*  Find more information and updates at https://mctools.github.io/mcpl/           */
 /*                                                                                 */
 /*  This file can be freely used as per the terms in the LICENSE file.             */
 /*                                                                                 */
@@ -69,9 +69,9 @@
 /***********************************************************************************/
 
 #define MCPL_VERSION_MAJOR 0
-#define MCPL_VERSION_MINOR 7
+#define MCPL_VERSION_MINOR 99
 #define MCPL_VERSION_PATCH 0
-#define MCPL_VERSION     700 /* (10000*MAJOR+100*MINOR+PATCH)   */
+#define MCPL_VERSION    9900 /* (10000*MAJOR+100*MINOR+PATCH)   */
 #define MCPL_FORMATVERSION 2 /* Format version of written files */
 
 #ifdef __cplusplus
@@ -329,6 +329,8 @@ int mcpl2ssw_app(int argc,char** argv);
 //                                                                                 //
 //  This file can be freely used as per the terms in the LICENSE file.             //
 //                                                                                 //
+//  Find more information and updates at https://mctools.github.io/mcpl/           //
+//                                                                                 //
 //  Written by Thomas Kittelmann, 2015-2016.                                       //
 //                                                                                 //
 /////////////////////////////////////////////////////////////////////////////////////
@@ -336,14 +338,6 @@ int mcpl2ssw_app(int argc,char** argv);
 
 //////
 //
-// TODO:
-//  * Implement --ignore flag for --merge.
-//
-// Planned features delayed for next release (not implemented yet):
-//  * Don't require code to calloc and keep track of their own mcpl_particle_t instance.
-//  * mcpl_gzip_file and mcpl_closeandgzip_outfile must return status indicating
-//    success or not (to know if .mcpl or .mcpl.gz file is the result).
-//
 //Possible future developments:
 //
 //  1) Support for particle groups ("events"). The file writing interface would
@@ -389,7 +383,7 @@ int mcpl2ssw_app(int argc,char** argv);
 // 8) Consider writing .mcpl.gz files directly (through a large buffer
 //    presumably). Or to have compressed blocks internally.
 //
-// 9) Should use unsigned char* rather than char* for buffers.
+// 9) Should use unsigned char* rather than char* for buffers?
 //
 //////
 
@@ -4159,11 +4153,12 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("Usage:\n");
   printf("  %s [dump-options] FILE\n",progname);
   printf("  %s --merge [merge-options] FILE1 FILE2\n",progname);
+  printf("  %s --extract [extract-options] FILE1 FILE2\n",progname);
   printf("  %s --repair FILE\n",progname);
   printf("  %s --version\n",progname);
   printf("  %s --help\n",progname);
   printf("\n");
-  printf("Dump Options:\n");
+  printf("Dump options:\n");
   printf("  By default include the info in the FILE header plus the first ten contained\n");
   printf("  particles. Modify with the following options:\n");
   assert(MCPLIMP_TOOL_DEFAULT_NLIMIT==10);
@@ -4174,13 +4169,17 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   printf("  -sN             : Skip past the first N particles in the file (default %i).\n",MCPLIMP_TOOL_DEFAULT_NSKIP);
   printf("  -bKEY           : Dump binary blob stored under KEY to standard output.\n");
   printf("\n");
-  printf("Merge Options:\n");
+  printf("Merge options:\n");
   printf("  -m, --merge FILE1 FILE2\n");
   printf("                    Appends the particle contents in FILE2 to the end of FILE1.\n");
-  printf("                    Note that this will fail unless FILE1 and FILE2 have iden-\n");
-  printf("                    tical headers (but see option --ignore below).\n");
-  printf("  -i, --ignore      Ignore comments and binary blobs in FILE2. This allows some\n");
-  printf("                    otherwise forbidden merges, but some info might get lost.\n");
+  printf("                    Note that this will fail unless FILE1 and FILE2 have compa-\n");
+  printf("                    tible headers.\n");
+  printf("\n");
+  printf("Extract options:\n");
+  printf("  -e, --extract FILE1 FILE2\n");
+  printf("                    Extracts particles from FILE1 into a new FILE2.\n");
+  printf("  -lN, -sN          Select range of particles in FILE1 (as above).\n");
+  printf("  -pPDGCODE         select particles of type given by PDGCODE.\n");
   printf("\n");
   printf("Other options:\n");
   printf("  -r, --repair FILE\n");
@@ -4192,16 +4191,45 @@ int mcpl_tool_usage( char** argv, const char * errmsg ) {
   return 0;
 }
 
+int mcpl_str2int(const char* str, size_t len, int64_t* res)
+{
+  //portable 64bit str2int with error checking.
+  *res = 0;
+  if (!len)
+    len=strlen(str);
+  if (!len)
+    return 0;
+  int sign = 1;
+  if (str[0]=='-') {
+    sign = -1;
+    len -= 1;
+    str += 1;
+  }
+  int64_t tmp = 0;
+  for (size_t i=0; i<len; ++i) {
+    if (str[i]<'0'||str[i]>'9') {
+      return 0;
+    }
+    tmp *= 10;
+    tmp += str[i] - '0';
+  }
+  if (tmp > INT64_MAX)
+    return 0;
+  *res = sign * tmp;
+  return 1;
+}
+
 int mcpl_tool(int argc,char** argv) {
   const char * filename1 = 0;
   const char * filename2 = 0;
   const char * blobkey = 0;
+  const char * pdgcode_str = 0;
   int opt_justhead = 0;
   int opt_nohead = 0;
   int64_t opt_num_limit = -1;
   int64_t opt_num_skip = -1;
   int opt_merge = 0;
-  int opt_ignore = 0;
+  int opt_extract = 0;
   int opt_repair = 0;
   int opt_version = 0;
 
@@ -4229,18 +4257,26 @@ int mcpl_tool(int argc,char** argv) {
           blobkey = a+j+1;
           break;
         }
+        if (a[j]=='p') {
+          if (pdgcode_str)
+            return mcpl_tool_usage(argv,"-p specified more than once");
+          if (j+1==n)
+            return mcpl_tool_usage(argv,"Missing argument for -p");
+          pdgcode_str = a+j+1;
+          break;
+        }
+
         switch(a[j]) {
           case 'h': return mcpl_tool_usage(argv,0);
           case 'j': opt_justhead = 1; break;
           case 'n': opt_nohead = 1; break;
           case 'm': opt_merge = 1; break;
-          case 'i': opt_ignore = 1; break;
+          case 'e': opt_extract = 1; break;
           case 'r': opt_repair = 1; break;
           case 'v': opt_version = 1; break;
           case 'l': consume_digit = &opt_num_limit; break;
           case 's': consume_digit = &opt_num_skip; break;
           default:
-            printf("%c\n",a[j]);
             return mcpl_tool_usage(argv,"Unrecognised option");
         }
         if (consume_digit) {
@@ -4256,7 +4292,7 @@ int mcpl_tool(int argc,char** argv) {
       const char * lo_justhead = "justhead";
       const char * lo_nohead = "nohead";
       const char * lo_merge = "merge";
-      const char * lo_ignore = "ignore";
+      const char * lo_extract = "extract";
       const char * lo_repair = "repair";
       const char * lo_version = "version";
       //Use strstr instead of "strcmp(a,"--help")==0" to support shortened
@@ -4265,7 +4301,7 @@ int mcpl_tool(int argc,char** argv) {
       else if (strstr(lo_justhead,a)==lo_justhead) opt_justhead = 1;
       else if (strstr(lo_nohead,a)==lo_nohead) opt_nohead = 1;
       else if (strstr(lo_merge,a)==lo_merge) opt_merge = 1;
-      else if (strstr(lo_ignore,a)==lo_ignore) opt_ignore = 1;
+      else if (strstr(lo_extract,a)==lo_extract) opt_extract = 1;
       else if (strstr(lo_repair,a)==lo_repair) opt_repair = 1;
       else if (strstr(lo_version,a)==lo_version) opt_version = 1;
       else return mcpl_tool_usage(argv,"Unrecognised option");
@@ -4279,10 +4315,17 @@ int mcpl_tool(int argc,char** argv) {
       return mcpl_tool_usage(argv,"Bad arguments");
     }
   }
-  int number_dumpopts = (opt_justhead + opt_nohead + (opt_num_limit!=-1) + (opt_num_skip!=-1) + (blobkey!=0));
+
+  if ( opt_extract==0 && pdgcode_str )
+    return mcpl_tool_usage(argv,"-p can only be used with --extract.");
+
+  int number_dumpopts = (opt_justhead + opt_nohead + (blobkey!=0));
+  if (opt_extract==0)
+    number_dumpopts += (opt_num_limit!=-1) + (opt_num_skip!=-1);
   int any_dumpopts = number_dumpopts != 0;
-  int any_mergeopts = (opt_merge + opt_ignore)!=0;
-  if (any_dumpopts+any_mergeopts+opt_repair+opt_version>1)
+  int any_extractopts = (opt_extract!=0||pdgcode_str!=0);
+  int any_mergeopts = (opt_merge!=0);
+  if (any_dumpopts+any_mergeopts+any_extractopts+opt_repair+opt_version>1)
     return mcpl_tool_usage(argv,"Conflicting options specified.");
 
   if (blobkey&&(number_dumpopts>1))
@@ -4295,14 +4338,9 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
-  if (opt_ignore&&!opt_merge)
-    return mcpl_tool_usage(argv,"Use --ignore only with --merge.");
-
   if (opt_merge) {
     if (!filename2)
       return mcpl_tool_usage(argv,"Must specify two input files with --merge.");
-    if (opt_ignore)
-      return mcpl_tool_usage(argv,"--ignore is not implemented yet.");
 
     if (!mcpl_can_merge(filename1,filename2))
       return mcpl_tool_usage(argv,"Requested files are incompatible for merge as they have different header info.");
@@ -4311,6 +4349,53 @@ int mcpl_tool(int argc,char** argv) {
     return 0;
   }
 
+  if (opt_extract) {
+    if (!filename2)
+      return mcpl_tool_usage(argv,"Must specify both input and output files with --extract.");
+
+    mcpl_file_t fi = mcpl_open_file(filename1);
+    mcpl_outfile_t fo = mcpl_create_outfile(filename2);
+    mcpl_transfer_metadata(fi, fo);
+    uint64_t fi_nparticles = mcpl_hdr_nparticles(fi);
+
+    char comment[1024];
+    sprintf(comment, "mcpltool: extracted particles from file with %" PRIu64 " particles",fi_nparticles);
+    mcpl_hdr_add_comment(fo,comment);
+
+    int32_t pdgcode_select = 0;
+    if (pdgcode_str) {
+      int64_t pdgcode64;
+      if (!mcpl_str2int(pdgcode_str, 0, &pdgcode64) || pdgcode64<INT32_MIN || pdgcode64>INT32_MAX || !pdgcode64)
+        return mcpl_tool_usage(argv,"Must specify non-zero 32bit integer as argument to -p.");
+      pdgcode_select = (int32_t)pdgcode64;
+    }
+
+    if (opt_num_skip>0)
+      mcpl_seek(fi,(uint64_t)opt_num_skip);
+
+    uint64_t left = opt_num_limit>0 ? (uint64_t)opt_num_limit : UINT64_MAX;
+    uint64_t added = 0;
+    const mcpl_particle_t* particle;
+    while ( left-- && ( particle = mcpl_read(fi) ) ) {
+      if (pdgcode_select && pdgcode_select!= particle->pdgcode)
+        continue;
+      mcpl_add_particle(fo,particle);
+      ++added;
+    }
+
+    char *fo_filename = (char*)malloc(strlen(mcpl_outfile_filename(fo))+4);
+    fo_filename[0] = '\0';
+    strcat(fo_filename,mcpl_outfile_filename(fo));
+    if (mcpl_closeandgzip_outfile_rc(fo))
+      strcat(fo_filename,".gz");
+    mcpl_close_file(fi);
+
+    printf("MCPL: Succesfully extracted %" PRIu64 " / %" PRIu64 " particles from %s into %s\n",
+           added,fi_nparticles,filename1,fo_filename);
+    free(fo_filename);
+    return 0;
+  }
+
   if (filename2)
     return mcpl_tool_usage(argv,"Too many arguments.");