diff --git a/entity_view_mode.module b/entity_view_mode.module
index cec996e..a83ed06 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,37 +266,37 @@ 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];
-    list($id, , $bundle) = entity_extract_ids($entity_type, $entity);
-
-    $suggestions = &$variables['theme_hook_suggestions'];
-
-    // Ensure the base suggestions exist and if not, add them.
-    if (!in_array("{$entity_type}__{$bundle}", $suggestions)) {
-      // The entity-type__bundle suggestion is typically "first".
-      array_unshift($suggestions, "{$entity_type}__{$bundle}");
-    }
-    if (!in_array("{$entity_type}__{$id}", $suggestions)) {
-      // The entity-type__id suggestion is always "last".
-      array_push($suggestions, "{$entity_type}__{$id}");
-    }
+function entity_view_mode_template_suggest_view_mode(&$variables, $hook) {
 
-    // Add view mode suggestions based on the location of the base suggestions.
-    if (!in_array("{$entity_type}__{$bundle}__{$view_mode}", $suggestions)) {
-      $index = array_search("{$entity_type}__{$bundle}__{$view_mode}", $suggestions);
-      array_splice($suggestions, $index + 1, 0, "{$entity_type}__{$bundle}__{$view_mode}");
-    }
-    if (!in_array("{$entity_type}__{$id}__{$view_mode}", $suggestions)) {
-      $index = array_search("{$entity_type}__{$id}", $suggestions);
-      array_splice($suggestions, $index + 1, 0, "{$entity_type}__{$id}__{$view_mode}");
-    }
+  $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'];
+
+  // Ensure the base suggestions exist and if not, add them.
+  if (!in_array("{$entity_type}__{$bundle}", $suggestions)) {
+    // The entity-type__bundle suggestion is typically "first".
+    array_unshift($suggestions, "{$entity_type}__{$bundle}");
+  }
+  if (!in_array("{$entity_type}__{$id}", $suggestions)) {
+    // The entity-type__id suggestion is always "last".
+    array_push($suggestions, "{$entity_type}__{$id}");
+  }
+
+  // Add view mode suggestions based on the location of the base suggestions.
+  if (!in_array("{$entity_type}__{$bundle}__{$view_mode}", $suggestions)) {
+    $index = array_search("{$entity_type}__{$bundle}__{$view_mode}", $suggestions);
+    array_splice($suggestions, $index + 1, 0, "{$entity_type}__{$bundle}__{$view_mode}");
+  }
+  if (!in_array("{$entity_type}__{$id}__{$view_mode}", $suggestions)) {
+    $index = array_search("{$entity_type}__{$id}", $suggestions);
+    array_splice($suggestions, $index + 1, 0, "{$entity_type}__{$id}__{$view_mode}");
   }
 }
 
