diff --git a/contrib/smarty/plugins/function.iconPath.php b/contrib/smarty/plugins/function.iconPath.php
new file mode 100644
index 0000000000000000000000000000000000000000..31ae49ef26fd0c785823f05b1bdb49ae8961be28
--- /dev/null
+++ b/contrib/smarty/plugins/function.iconPath.php
@@ -0,0 +1,18 @@
+<?php
+
+function smarty_function_iconPath($params, &$smarty)
+{
+  $config = session::global_get('config');
+
+  /* Set theme */
+  $theme = "default";
+  if (isset ($config)) {
+    $theme = $config->get_cfg_value("theme", "default");
+    if (!isset(IconTheme::$themes[$theme])) {
+      $theme = 'default';
+    }
+  }
+
+  return IconTheme::$themes[$theme]->FindIcon($params['context'], $params['icon'], $params['size']);
+}
+?>
diff --git a/html/main.php b/html/main.php
index 5f00ea170865e0e8d7fc8ffed7f723d373c260c1..31eef91df3da5742e449349214a64ae83f48f788 100644
--- a/html/main.php
+++ b/html/main.php
@@ -62,6 +62,7 @@ if ($_SERVER['REMOTE_ADDR'] != $ui->ip) {
   exit;
 }
 $config = session::global_get('config');
+IconTheme::loadThemes('themes');
 
 /* If SSL is forced, just forward to the SSL enabled site */
 if (($config->get_cfg_value("forcessl") == "TRUE") && ($ssl != '')) {
diff --git a/include/class_IconTheme.inc b/include/class_IconTheme.inc
new file mode 100644
index 0000000000000000000000000000000000000000..5aaa40cf843ac5806f44b885a5f2e3031ceb1788
--- /dev/null
+++ b/include/class_IconTheme.inc
@@ -0,0 +1,155 @@
+<?php
+
+class IconThemeDir
+{
+  private $Size;
+  private $MinSize;
+  private $MaxSize;
+  private $Type      = 'Threshold';
+  private $Threshold = 2;
+
+  function __construct($infos)
+  {
+    $this->Size     = $infos['Size'];
+    $this->MinSize  = $infos['Size'];
+    $this->MaxSize  = $infos['Size'];
+    foreach (array('Type', 'MaxSize', 'MinSize', 'Threshold') as $key) {
+      if (isset($infos[$key])) {
+        $this->$key = $infos[$key];
+      }
+    }
+    /* Thanks to this Threshold and Scaled are the same */
+    if ($this->Type == 'Threshold') {
+      $this->MinSize = $this->Size - $this->Threshold;
+      $this->MaxSize = $this->Size + $this->Threshold;
+    }
+  }
+
+  function MatchesSize($size)
+  {
+    switch ($this->Type) {
+      case 'Fixed':
+        return ($this->Size == $size);
+      case 'Threshold':
+      case 'Scalable':
+        return (($this->MinSize <= $size) && ($size <= $this->MaxSize));
+    }
+  }
+
+  function SizeDistance($size)
+  {
+    switch ($this->Type) {
+      case 'Fixed':
+        return abs($this->Size - $size);
+      case 'Threshold':
+      case 'Scalable':
+        if ($size < $this->MinSize) {
+          return $this->MinSize - $size;
+        }
+        if ($size > $this->MaxSize) {
+          return $size - $this->MaxSize;
+        }
+        return 0;
+    }
+  }
+}
+
+class IconTheme
+{
+  private $subdirs = array();
+  private $path;
+  private $parent;
+
+  function __construct($folder, $default_parent = 'default')
+  {
+    $this->path = $folder;
+    $datas  = parse_ini_file($folder.'/index.theme', TRUE, INI_SCANNER_RAW);
+    if ($datas === FALSE) {
+      throw new Exception('Error while parsing theme file');
+    }
+    $dirs   = preg_split('/,/', $datas['Icon Theme']['Directories']);
+    foreach ($dirs as $name) {
+      $this->subdirs[strtolower($datas[$name]['Context'])][$name] = new IconThemeDir($datas[$name]);
+    }
+
+    if (isset($datas['Inherits'])) {
+      $this->parent = $datas['Inherits'];
+    } else {
+      $this->parent = $default_parent;
+    }
+  }
+
+  function FindIcon($context, $icon, $size)
+  {
+    $context = strtolower($context);
+    return $this->FindIconHelper($context, $icon, $size);
+  }
+
+  function FindIconHelper($context, $icon, $size)
+  {
+    $filename = $this->LookupIcon($context, $icon, $size);
+    if ($filename != NULL) {
+      return $filename;
+    }
+
+    if ($this->parent !== NULL) {
+      if (isset(self::$themes[$this->parent])) {
+        $parent = self::$themes[$this->parent];
+      } else {
+        $parent = self::$themes['default'];
+      }
+      return $parent->FindIconHelper($context, $icon, $size);
+    }
+
+    return NULL;
+  }
+
+  function LookupIcon($context, $iconname, $size)
+  {
+    foreach ($this->subdirs[$context] as $path => &$subdir) {
+      if ($subdir->MatchesSize($size)) {
+        foreach (array('png', 'svg', 'xpm') as $extension) {
+          $filename = $this->path.'/'.$path.'/'.$iconname.'.'.$extension;
+          if (file_exists($filename)) {
+            return $filename;
+          }
+        }
+      }
+    }
+    unset($subdir);
+    $minimal_size = PHP_INT_MAX;
+    foreach ($this->subdirs[$context] as $path => &$subdir) {
+      if (($sizedistance = $subdir->SizeDistance($size)) < $minimal_size) {
+        foreach (array('png', 'svg', 'xpm') as $extension) {
+          $filename = $this->path.'/'.$path.'/'.$iconname.'.'.$extension;
+          if (file_exists($filename)) {
+            $closest_filename = $filename;
+            $minimal_size     = $sizedistance;
+          }
+        }
+      }
+    }
+    unset($subdir);
+    if (isset($closest_filename)) {
+      return $closest_filename;
+    }
+    return NULL;
+  }
+
+  static public $themes;
+  static public function loadThemes($path)
+  {
+    if ($dir = opendir("$path")) {
+      while (($file = readdir($dir)) !== FALSE) {
+        if (file_exists("$path/$file/index.theme") && !preg_match("/^\./", $file)) {
+          try {
+            self::$themes[$file] = new IconTheme("$path/$file");
+          } catch (Exception $e) {
+          }
+        }
+      }
+    }
+  }
+}
+
+?>
diff --git a/plugins/config/class_configInLdap.inc b/plugins/config/class_configInLdap.inc
index aed43469e2399caeafff848cf2e25ec700e6a8f0..4ba2a69bca5e4ef8d7dd2e3757e2e792c7a02e78 100644
--- a/plugins/config/class_configInLdap.inc
+++ b/plugins/config/class_configInLdap.inc
@@ -495,7 +495,7 @@ class configInLdap extends simplePlugin
   static function get_themes()
   {
     $themesdir  = '../ihtml/themes/';
-    $themes     = array();
+    $themes     = array_keys(IconTheme::$themes);
     if ($dir = opendir("$themesdir")) {
       while (($file = readdir($dir)) !== FALSE) {
         if (is_dir("$themesdir/$file") && !preg_match("/^\./", $file)) {
@@ -503,7 +503,7 @@ class configInLdap extends simplePlugin
         }
       }
     }
-    return $themes;
+    return array_unique($themes);
   }
 }
 ?>