diff --git a/entity_view_mode.module b/entity_view_mode.module
index cec996e..cd35fe0 100644
--- a/entity_view_mode.module
+++ b/entity_view_mode.module
@@ -216,6 +216,45 @@ function field_entity_view_mode_delete($view_mode, $entity_type) {
 }
 
 /**
+ * Implements hook_theme_registry_alter().
+ *
+ * There's no consistent way to find an entity in the theme stack. To avoid conflicts, all
+ * entity themes in the registry are annotated with the name of the entity's key in the
+ * render element array. The preprocess function is only added to specific theme entities.
+ *
+ * Currently all entities are themed with a render element instead of variables.
+ * field_attach_view() adds entity type and bundle info to the render elements.
+ *
+ * To extend template suggestions to other entities, implement hook_theme_registry_alter()
+ * in another module and add an 'entity key' to the registry for the theme and append
+ * the entity_view_mode_template_suggest_view_mode() function to its preprocess functions.
+ */
+function entity_view_mode_theme_registry_alter(&$theme_registry) {
+
+  // Overload theme registry with property name of entity in render element or variables.
+  $entity_themes = array(
+
+    // Node and user module are required, so these themes are always present.
+    'node' => '#node',
+    'user_profile' => '#account',
+
+    // These entity themes are optional core or contrib.
+    'comment' => '#comment',
+    'entity' => '#entity',
+    'fieldable_panels_pane' => '#element',
+    'file_entity' => '#file',
+    'taxonomy_term' => '#term',
+  );
+
+  foreach ($entity_themes as $hook => $entity_key) {
+    if (isset($theme_registry[$hook])) {
+      $theme_registry[$hook]['entity key'] = $entity_key;
+      $theme_registry[$hook]['preprocess functions'][] = 'entity_view_mode_template_suggest_view_mode';
+    }
+  }
+}
+
+/**
  * Implements hook_preprocess().
  *
  * Add template suggestions for an entity based on view modes if they do not
@@ -227,14 +266,15 @@ function field_entity_view_mode_delete($view_mode, $entity_type) {
  * - entity-type__id
  * - entity-type__id__view-mode (highest priority = last in the array)
  */
-function entity_view_mode_preprocess(&$variables, $hook) {
-  // @todo Improve checking of entity type based on hook. Some entities do not
-  // match 1:1 like file_entity and user_profile.
-  if (!empty($variables[$hook]) && !empty($variables['theme_hook_suggestions']) && entity_get_info($hook)) {
-    $view_mode = $variables['elements']['#view_mode'];
-
-    $entity_type = $hook;
-    $entity = $variables[$entity_type];
+function entity_view_mode_template_suggest_view_mode(&$variables, $hook) {
+
+    $hooks = theme_get_registry(FALSE);
+    $entity_key = $hooks[$hook]['entity key'];
+    $render_element = $variables[$hooks[$hook]['render element']];
+
+    $view_mode = $render_element['#view_mode'];
+    $entity_type = $render_element['#entity_type'];
+    $entity = $render_element[$entity_key];
     list($id, , $bundle) = entity_extract_ids($entity_type, $entity);
 
     $suggestions = &$variables['theme_hook_suggestions'];
@@ -258,7 +298,6 @@ function entity_view_mode_preprocess(&$variables, $hook) {
       $index = array_search("{$entity_type}__{$id}", $suggestions);
       array_splice($suggestions, $index + 1, 0, "{$entity_type}__{$id}__{$view_mode}");
     }
-  }
 }
 
 function entity_view_mode_get_enabled_bundles($entity_type, $view_mode_name) {
