diff --git a/var/spack/repos/builtin/packages/mumps/package.py b/var/spack/repos/builtin/packages/mumps/package.py
index 44a37903cc8dc9d05134d2e3c212d5eced651c5a..5c120c37df8758d39cb9f14340b605c4bed9644e 100644
--- a/var/spack/repos/builtin/packages/mumps/package.py
+++ b/var/spack/repos/builtin/packages/mumps/package.py
@@ -20,10 +20,10 @@ class Mumps(Package):
     variant('complex', default=True, description='Activate the compilation of cmumps and/or zmumps')
     variant('idx64', default=False, description='Use int64_t/integer*8 as default index type')
 
-    
+
     depends_on('scotch + esmumps', when='~ptscotch+scotch')
     depends_on('scotch + esmumps + mpi', when='+ptscotch')
-    depends_on('metis', when='~parmetis+metis')
+    depends_on('metis', when='+metis')
     depends_on('parmetis', when="+parmetis")
     depends_on('blas')
     depends_on('lapack')
@@ -38,11 +38,11 @@ class Mumps(Package):
     def write_makefile_inc(self):
         if ('+parmetis' in self.spec or '+ptscotch' in self.spec) and '+mpi' not in self.spec:
             raise RuntimeError('You cannot use the variants parmetis or ptscotch without mpi')
-        
+
         makefile_conf = ["LIBBLAS = -L%s -lblas" % self.spec['blas'].prefix.lib]
 
         orderings = ['-Dpord']
-        
+
         if '+ptscotch' in self.spec or '+scotch' in self.spec:
             join_lib = ' -l%s' % ('pt' if '+ptscotch' in self.spec else '')
             makefile_conf.extend(
@@ -54,15 +54,19 @@ def write_makefile_inc(self):
             if '+ptscotch' in self.spec:
                 orderings.append('-Dptscotch')
 
-        if '+parmetis' in self.spec or '+metis' in self.spec:
+        if '+parmetis' in self.spec and '+metis' in self.spec:
             libname = 'parmetis' if '+parmetis' in self.spec else 'metis'
             makefile_conf.extend(
-                ["IMETIS = -I%s" % self.spec[libname].prefix.include,
-                 "LMETIS = -L%s -l%s" % (self.spec[libname].prefix.lib, libname)])
+                ["IMETIS = -I%s" % self.spec['parmetis'].prefix.include,
+                 "LMETIS = -L%s -l%s -L%s -l%s" % (self.spec['parmetis'].prefix.lib, 'parmetis',self.spec['metis'].prefix.lib, 'metis')])
+
+            orderings.append('-Dparmetis')
+        elif '+metis' in self.spec:
+            makefile_conf.extend(
+                ["IMETIS = -I%s" % self.spec['metis'].prefix.include,
+                 "LMETIS = -L%s -l%s" % (self.spec['metis'].prefix.lib, 'metis')])
 
             orderings.append('-Dmetis')
-            if '+parmetis' in self.spec:
-                orderings.append('-Dparmetis')
 
         makefile_conf.append("ORDERINGSF = %s" % (' '.join(orderings)))
 
@@ -101,12 +105,12 @@ def write_makefile_inc(self):
         # compiler possible values are -DAdd_, -DAdd__ and/or -DUPPER
         makefile_conf.append("CDEFS   = -DAdd_")
 
-        
+
         makefile_inc_template = join_path(os.path.dirname(self.module.__file__),
                                           'Makefile.inc')
         with open(makefile_inc_template, "r") as fh:
             makefile_conf.extend(fh.read().split('\n'))
-        
+
         with working_dir('.'):
             with open("Makefile.inc", "w") as fh:
                 makefile_inc = '\n'.join(makefile_conf)
@@ -130,7 +134,7 @@ def install(self, spec, prefix):
                 make_libs.append('zexamples')
 
         self.write_makefile_inc()
-                
+
         make(*make_libs)
 
         install_tree('lib', prefix.lib)
diff --git a/var/spack/repos/builtin/packages/parmetis/enable_external_metis.patch b/var/spack/repos/builtin/packages/parmetis/enable_external_metis.patch
new file mode 100644
index 0000000000000000000000000000000000000000..514781b8b88881d494aaf47bbfd7c5e1384fba81
--- /dev/null
+++ b/var/spack/repos/builtin/packages/parmetis/enable_external_metis.patch
@@ -0,0 +1,13 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index ca945dd..1bf94e9 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -33,7 +33,7 @@ include_directories(${GKLIB_PATH})
+ include_directories(${METIS_PATH}/include)
+
+ # List of directories that cmake will look for CMakeLists.txt
+-add_subdirectory(${METIS_PATH}/libmetis ${CMAKE_BINARY_DIR}/libmetis)
++#add_subdirectory(${METIS_PATH}/libmetis ${CMAKE_BINARY_DIR}/libmetis)
+ add_subdirectory(include)
+ add_subdirectory(libparmetis)
+ add_subdirectory(programs)
diff --git a/var/spack/repos/builtin/packages/parmetis/package.py b/var/spack/repos/builtin/packages/parmetis/package.py
index c897dec7e44b4768e4e9abe9e94f5b41b4a4a1a1..c691cf4191d1ad45f08f8f1be4ddb2831fe6df6f 100644
--- a/var/spack/repos/builtin/packages/parmetis/package.py
+++ b/var/spack/repos/builtin/packages/parmetis/package.py
@@ -25,9 +25,6 @@
 
 from spack import *
 
-# FIXME : lot of code is duplicated from packages/metis/package.py . Inheriting from there may reduce
-# FIXME : the installation rules to just a few lines
-
 
 class Parmetis(Package):
     """
@@ -43,13 +40,17 @@ class Parmetis(Package):
     variant('debug', default=False, description='Builds the library in debug mode')
     variant('gdb', default=False, description='Enables gdb support')
 
-    variant('idx64', default=False, description='Use int64_t as default index type')
-    variant('double', default=False, description='Use double precision floating point types')
-
     depends_on('cmake @2.8:')  # build dependency
     depends_on('mpi')
 
-    # FIXME : this should conflict with metis as it builds its own version internally
+    patch('enable_external_metis.patch')
+    depends_on('metis')
+
+    # bug fixes from PETSc developers
+    # https://bitbucket.org/petsc/pkg-parmetis/commits/1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b/raw/
+    patch('pkg-parmetis-1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b.patch')
+    # https://bitbucket.org/petsc/pkg-parmetis/commits/82409d68aa1d6cbc70740d0f35024aae17f7d5cb/raw/
+    patch('pkg-parmetis-82409d68aa1d6cbc70740d0f35024aae17f7d5cb.patch')
 
     depends_on('gdb', when='+gdb')
 
@@ -63,8 +64,8 @@ def install(self, spec, prefix):
 
         # FIXME : Once a contract is defined, MPI compilers should be retrieved indirectly via spec['mpi'] in case
         # FIXME : they use a non-standard name
-        options.extend(['-DGKLIB_PATH:PATH={metis_source}/GKlib'.format(metis_source=metis_source),
-                        '-DMETIS_PATH:PATH={metis_source}'.format(metis_source=metis_source),
+        options.extend(['-DGKLIB_PATH:PATH={metis_source}/GKlib'.format(metis_source=metis_source), # still need headers from METIS source, and they are not installed with METIS. shame...
+                        '-DMETIS_PATH:PATH={metis_source}'.format(metis_source=spec['metis'].prefix),
                         '-DCMAKE_C_COMPILER:STRING=mpicc',
                         '-DCMAKE_CXX_COMPILER:STRING=mpicxx'])
 
@@ -78,18 +79,7 @@ def install(self, spec, prefix):
         if '+gdb' in spec:
             options.append('-DGDB:BOOL=ON')
 
-        metis_header = join_path(metis_source, 'include', 'metis.h')
-
-        if '+idx64' in spec:
-            filter_file('IDXTYPEWIDTH 32', 'IDXTYPEWIDTH 64', metis_header)
-
-        if '+double' in spec:
-            filter_file('REALTYPEWIDTH 32', 'REALTYPEWIDTH 64', metis_header)
-
         with working_dir(build_directory, create=True):
             cmake(source_directory, *options)
             make()
             make("install")
-            # Parmetis build system doesn't allow for an external metis to be used, but doesn't copy the required
-            # metis header either
-            install(metis_header, self.prefix.include)
diff --git a/var/spack/repos/builtin/packages/parmetis/pkg-parmetis-1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b.patch b/var/spack/repos/builtin/packages/parmetis/pkg-parmetis-1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b.patch
new file mode 100644
index 0000000000000000000000000000000000000000..e6b8056c210ee81a4e1b53de95158fa00648ff34
--- /dev/null
+++ b/var/spack/repos/builtin/packages/parmetis/pkg-parmetis-1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b.patch
@@ -0,0 +1,77 @@
+From 1c1a9fd0f408dc4d42c57f5c3ee6ace411eb222b Mon Sep 17 00:00:00 2001
+From: Jed Brown <jed@59A2.org>
+Date: Fri, 12 Oct 2012 15:45:10 -0500
+Subject: [PATCH] ParMetis bug fixes reported by John Fettig [petsc-maint
+ #133631]
+
+'''
+I have also reported to to Karypis but have received zero
+response and he hasn't released any updates to the original release
+either.  At least he approved my forum posting so that other people
+can see the bug and the fix.
+http://glaros.dtc.umn.edu/gkhome/node/837
+'''
+
+Hg-commit: 1c2b9fe39201d404b493885093b5992028b9b8d4
+---
+ libparmetis/xyzpart.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/libparmetis/xyzpart.c b/libparmetis/xyzpart.c
+index 3a2c289..63abfcb 100644
+--- a/libparmetis/xyzpart.c
++++ b/libparmetis/xyzpart.c
+@@ -104,7 +104,7 @@ void IRBinCoordinates(ctrl_t *ctrl, graph_t *graph, idx_t ndims, real_t *xyz,
+ 
+     for (i=0; i<nbins; i++)
+       emarkers[i] = gmin + (gmax-gmin)*i/nbins;
+-    emarkers[nbins] = gmax*(1.0+2.0*REAL_EPSILON);
++    emarkers[nbins] = gmax*(1.0+copysign(1.0,gmax)*2.0*REAL_EPSILON);
+ 
+     /* get into a iterative backet boundary refinement */
+     for (l=0; l<5; l++) {
+@@ -152,7 +152,7 @@ void IRBinCoordinates(ctrl_t *ctrl, graph_t *graph, idx_t ndims, real_t *xyz,
+         }
+       }
+       nemarkers[0]     = gmin;
+-      nemarkers[nbins] = gmax*(1.0+2.0*REAL_EPSILON);
++      nemarkers[nbins] = gmax*(1.0+copysign(1.0,gmax)*2.0*REAL_EPSILON);
+       rcopy(nbins+1, nemarkers, emarkers);
+     }
+ 
+@@ -218,7 +218,7 @@ void RBBinCoordinates(ctrl_t *ctrl, graph_t *graph, idx_t ndims, real_t *xyz,
+ 
+     emarkers[0] = gmin;
+     emarkers[1] = gsum/gnvtxs;
+-    emarkers[2] = gmax*(1.0+2.0*REAL_EPSILON);
++    emarkers[2] = gmax*(1.0+(gmax < 0 ? -1. : 1.)*2.0*REAL_EPSILON);
+     cnbins = 2;
+ 
+     /* get into a iterative backet boundary refinement */
+@@ -227,7 +227,7 @@ void RBBinCoordinates(ctrl_t *ctrl, graph_t *graph, idx_t ndims, real_t *xyz,
+       iset(cnbins, 0, lcounts);
+       rset(cnbins, 0, lsums);
+       for (j=0, i=0; i<nvtxs;) {
+-        if (cand[i].key < emarkers[j+1]) {
++        if (cand[i].key <= emarkers[j+1]) {
+           lcounts[j]++;
+           lsums[j] += cand[i].key;
+           i++;
+@@ -272,12 +272,12 @@ void RBBinCoordinates(ctrl_t *ctrl, graph_t *graph, idx_t ndims, real_t *xyz,
+       
+       rsorti(cnbins, nemarkers);
+       rcopy(cnbins, nemarkers, emarkers);
+-      emarkers[cnbins] = gmax*(1.0+2.0*REAL_EPSILON);
++      emarkers[cnbins] = gmax*(1.0+(gmax < 0 ? -1. : 1.)*2.0*REAL_EPSILON);
+     }
+ 
+     /* assign the coordinate to the appropriate bin */
+     for (j=0, i=0; i<nvtxs;) {
+-      if (cand[i].key < emarkers[j+1]) {
++      if (cand[i].key <= emarkers[j+1]) {
+         bxyz[cand[i].val*ndims+k] = j;
+         i++;
+       }
+-- 
+2.1.1.1.g1fb337f
+
diff --git a/var/spack/repos/builtin/packages/parmetis/pkg-parmetis-82409d68aa1d6cbc70740d0f35024aae17f7d5cb.patch b/var/spack/repos/builtin/packages/parmetis/pkg-parmetis-82409d68aa1d6cbc70740d0f35024aae17f7d5cb.patch
new file mode 100644
index 0000000000000000000000000000000000000000..9651d553478d23109b95ee31edd57183183094d8
--- /dev/null
+++ b/var/spack/repos/builtin/packages/parmetis/pkg-parmetis-82409d68aa1d6cbc70740d0f35024aae17f7d5cb.patch
@@ -0,0 +1,35 @@
+From 82409d68aa1d6cbc70740d0f35024aae17f7d5cb Mon Sep 17 00:00:00 2001
+From: Sean Farley <sean@mcs.anl.gov>
+Date: Tue, 20 Mar 2012 11:59:44 -0500
+Subject: [PATCH] parmetis: fix bug reported by jfettig; '<' to '<=' in xyzpart
+
+Hg-commit: 2dd2eae596acaabbc80e0ef875182616f868dbc2
+---
+ libparmetis/xyzpart.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libparmetis/xyzpart.c b/libparmetis/xyzpart.c
+index 307aed9..3a2c289 100644
+--- a/libparmetis/xyzpart.c
++++ b/libparmetis/xyzpart.c
+@@ -111,7 +111,7 @@ void IRBinCoordinates(ctrl_t *ctrl, graph_t *graph, idx_t ndims, real_t *xyz,
+       /* determine bucket counts */
+       iset(nbins, 0, lcounts);
+       for (j=0, i=0; i<nvtxs;) {
+-        if (cand[i].key < emarkers[j+1]) {
++        if (cand[i].key <= emarkers[j+1]) {
+           lcounts[j]++;
+           i++;
+         }
+@@ -158,7 +158,7 @@ void IRBinCoordinates(ctrl_t *ctrl, graph_t *graph, idx_t ndims, real_t *xyz,
+ 
+     /* assign the coordinate to the appropriate bin */
+     for (j=0, i=0; i<nvtxs;) {
+-      if (cand[i].key < emarkers[j+1]) {
++      if (cand[i].key <= emarkers[j+1]) {
+         bxyz[cand[i].val*ndims+k] = j;
+         i++;
+       }
+-- 
+2.1.1.1.g1fb337f
+