diff --git a/cmake/modules/lcgsoft-macros.cmake b/cmake/modules/lcgsoft-macros.cmake
index c289ab7a8552c7d30e8d444ac96155813affaef7..2904320695cf4a581fa93fd73ce9a02d5e716062 100644
--- a/cmake/modules/lcgsoft-macros.cmake
+++ b/cmake/modules/lcgsoft-macros.cmake
@@ -361,21 +361,25 @@ macro(LCGPackage_Add name)
       # Process .post-install.sh scripts
       if (POST_INSTALL)
       set (post-install_name "${CMAKE_SOURCE_DIR}/cmake/scripts/post-install.sh")
+      set (gen_post_install_info_cmd "${CMAKE_SOURCE_DIR}/cmake/scripts/gen_post_install_info.py")
       set (path_map)
-      foreach (dep ${${targetname}-dependencies};${targetname})
+      set (_expanded_deps)
+      LCG_append_depends(${targetname} _expanded_deps)
+      list(SORT _expanded_deps)
+      foreach (dep ${_expanded_deps};${targetname})
         string(REGEX MATCH "${dependency_split_pattern}" dep_zero "${dep}")
         set (dep_name    "${CMAKE_MATCH_1}")
-        set (dep_version "${CMAKE_MATCH_2}") 
+        set (dep_version "${CMAKE_MATCH_2}")
         if (${LCG_VERSION} VERSION_GREATER 68 OR ${LCG_VERSION} MATCHES "root6")
           set (path_map "${${dep}_home}:${${dep_name}_directory_name}/${dep_version}-${${dep}_hash}/${LCG_system} ${path_map}")
         else ()
           set (path_map "${${dep}_home}:${${dep_name}_directory_name}/${dep_version}/${LCG_system} ${path_map}")
-        endif() 
+        endif()
       endforeach()
-      ExternalProject_Add_Step(${targetname}  copy_post-install COMMENT "Copying .post-install.sh file for ${targetname}"
+      ExternalProject_Add_Step(${targetname}  copy_post-install COMMENT "Prepare post-install for ${targetname}"
           COMMAND ${CMAKE_COMMAND} -E copy ${post-install_name} ${${name}_home}/.post-install.sh
-          COMMAND $ENV{SHELL} -c "chmod +x ${${name}_home}/.post-install.sh"
-          COMMAND $ENV{SHELL} -c "${post-install_name} generate ${CMAKE_INSTALL_PREFIX} ${${targetname}_home}  '${path_map}'"
+          COMMAND chmod +x ${${name}_home}/.post-install.sh
+          COMMAND ${gen_post_install_info_cmd} ${CMAKE_INSTALL_PREFIX} ${${targetname}_home} "${path_map}"
           COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_BINARY_DIR}/timestamps/${targetname}-stop.timestamp
           DEPENDEES setup_environment
       )
diff --git a/cmake/scripts/gen_post_install_info.py b/cmake/scripts/gen_post_install_info.py
new file mode 100755
index 0000000000000000000000000000000000000000..3f734608e6f6e7796000e1f208deb7a56d600e70
--- /dev/null
+++ b/cmake/scripts/gen_post_install_info.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python
+'''
+Python rewrite of the original post-install.sh.
+'''
+import os
+import sys
+
+LISTNAME = '.filelist'
+
+def skip_dir(root, name):
+    '''
+    Tell if a directory should not be searched for files.
+    
+    @param root: parent path
+    @param name: name of the directory
+    '''
+    # FIXME: can the logic be simplified?
+    return ((name == 'logs') or
+            ('datafiles' in name) or
+            (root.endswith('share') and (
+                name.startswith('LHAPDF') or
+                name.startswith('sources'))
+            ))
+
+
+def generate(lcg_home, pkg_home, path_map):
+    '''
+    Do something...
+    
+    @param lcg_home: root of LCG installation
+    '''
+    list_file = open(os.path.join(pkg_home, LISTNAME), 'w')
+    list_file.write(lcg_home + '\n')
+
+    # add real (no-symlink) names to the mappings
+    path_map.update((os.path.realpath(old), new)
+                    for old, new in path_map.items())
+    
+    # write all the mappings
+    list_file.writelines('%s->%s\n' % (old, new)
+                         for old, new in path_map.items() if old and new)
+    
+    for root, dirs, files in os.walk(pkg_home):
+        dirs[:] = [d for d in dirs
+                   if not skip_dir(root, d)]
+        for filename in files:
+            # FIXME we could quickly ignore files from the name
+            # e.g. estension == '.so'
+            
+            filename = os.path.join(root, filename)
+            
+            content = open(filename, 'rb').read()
+            if '\0' in content:
+                # it's a binary (or UTF-16) file
+                # See http://stackoverflow.com/q/898669
+                continue
+            
+            for old in path_map:
+                if old in content:
+                    list_file.write(os.path.relpath(filename, pkg_home) + '\n')
+                    break
+
+
+if __name__ == '__main__':
+    # FIXME: do we want many arguments or one space separated list?
+    path_map = {}
+    for arg in sys.argv[3:]:
+        path_map.update(spec.split(':', 1)
+                        for spec in arg.split())
+        
+    generate(sys.argv[1], sys.argv[2], path_map)
diff --git a/cmake/scripts/post-install.sh b/cmake/scripts/post-install.sh
index 70c01660fd125b9213f96030c88ddea03bf90955..c7d876020b3ca00f94f7b39a2c52607c52d4b814 100755
--- a/cmake/scripts/post-install.sh
+++ b/cmake/scripts/post-install.sh
@@ -3,75 +3,42 @@
 export LANG=C
 listname=".filelist"
 
-# === generate list of files
-if [ "generate" = "$1" ]; then
-  LCG_home="$2"
-  pkg_home="$3"
-  while [ ! -z "$4" ];do
-    path_map="$4 $path_map"
-    shift
-  done
-  list_file="$pkg_home/$listname"
-  tmp_file=$(mktemp -t lcg.XXX)
-  tmp_file_list=$(mktemp -t lcg.XXX)
-  
-  # prepare list of files
-  find $pkg_home -type f ! -path '*share/LHAPDF*'  \
-                        -o -path '*share/sources*' \
-                        -o -path '*datafiles*' -prune | grep -v "$pkg_home/logs"  > $tmp_file_list
-  # proceed depends
-  for map in $(echo "$path_map"); do
-    old_install_path="$(echo $map | cut -d: -f1)"
-    old_real_install_path="$(cd $old_install_path; pwd -P)"
-    new_directory_name="$(echo $map | cut -d: -f2)"
-    echo "$old_real_install_path->$new_directory_name"
-    echo "$old_install_path->$new_directory_name"
-    # find files
-    cat $tmp_file_list | while read name; do
-      # check that file is not binary
-      if perl -E 'exit((-B $ARGV[0])?1:0);' "$name"; then
-        if grep -q -- "$old_install_path" "$name" || grep -q -- "$old_real_install_path" "$name";then
-          echo $name | sed -e "s@$pkg_home/@@g"
-        fi
-      fi
-    done
-  done >> $tmp_file 
-  # prepare $list_file
-  echo $LCG_home > $list_file
-  cat $tmp_file | grep -- '->' >> $list_file
-  cat $tmp_file | sed '/->/d' | sort | uniq >> $list_file
-  rm -f $tmp_file
-  rm -f $tmp_file_list
-  exit 0
-fi
-# ===
-
 # === Replace install paths in files from filelist
 THIS="$0"
 PREFIX="$(/bin/sh -c "dirname $THIS")"
 
+# Use INSTALLDIR env variable or automatic RPM_INSTALL_DIR as target prefix
 while [ ! -d "$INSTALLDIR" ]; do
   [ ! -z "$RPM_INSTALL_PREFIX" ] && INSTALLDIR="$RPM_INSTALL_PREFIX" || read -e -p "Type new install directory : " INSTALLDIR
 done
 
+# extract old install dir from .filelist (should be first line)
 OLDINSTALLDIR="$(head -1 $PREFIX/$listname)"
-sed -i -e '1d' $PREFIX/$listname
+sed -i -e '1d' $PREFIX/$listname  # delete first line
 echo 
 echo "Replacing $OLDINSTALLDIR -> $INSTALLDIR"
 echo
 
 # prepare package list for replacing
 
+# loop over files (lines without '->')
 cat $PREFIX/$listname | grep -v -- '->' | while read name; do
+  test "$name" == ".filelist" && continue  # skip .filelist
   echo "=== Patching $name ... ==="
-  old=$(mktemp -t lcg.XXX)
+  old=$(mktemp -t lcg.XXXXX)
   cp -f "$PREFIX/$name" "$old"
-  # patch files
-  cat $PREFIX/$listname | grep -- '->' | while read line; do
-    olddir="$(echo $line | awk -F'->' '{print $1}')"
-    newdir="${INSTALLDIR}/$(echo $line | awk -F'->' '{print $2}')"   
-    sed -i -e "s@$olddir@$newdir@g" "$PREFIX/$name"
+  # loop over all target paths (after '->' delimiter)
+  cat $PREFIX/$listname | grep -- '->' | awk -F'->' '{print $2}'| sort | uniq | while read newpath; do
+    # loop over all source paths for given target path, use sorting by path length to resolve issues like /var/build/... and /build/...
+    # 1 target path is related with multiple (at least 2 -- real and 'usual') source paths  
+    cat $PREFIX/$listname | grep -- '->' | grep -- "$newpath" | awk -F'->' '{ print length($1) " " $0; }' | sort -r -n | cut -d ' ' -f 2- | while read line; do
+      olddir="$(echo $line | awk -F'->' '{print $1}')"
+      newdir="${INSTALLDIR}/$(echo $line | awk -F'->' '{print $2}')"   
+      # patching
+      test ! -z "$olddir" && test ! -z "$newdir" && sed -i -e "s@$olddir@$newdir@g" -e '/afs/s,/\.cern.ch,/cern.ch,g' "$PREFIX/$name"
+    done
   done 
+  # show diff
   diff -u "$old" "$PREFIX/$name"
   rm -f "$old"
   echo