old_contents: import json
  import collections
  
  import bleach
  
  
  def is_iterable(obj):
      return isinstance(obj, collections.Iterable)
  
  
  def is_iterable_but_not_string(obj):
      """Return True if ``obj`` is an iterable object that isn't a string."""
      return (is_iterable(obj) and not hasattr(obj, 'strip'))
  
  
  def strip_html(unclean, tags=None):
      """Sanitize a string, removing (as opposed to escaping) HTML tags
  
      :param unclean: A string to be stripped of HTML tags
  
      :return: stripped string
      :rtype: str
      """
      tags = tags or []
  
      # We make this noop for non-string, non-collection inputs so this function can be used with higher-order
      # functions, such as rapply (recursively applies a function to collections)
      if not isinstance(unclean, basestring) and not is_iterable(unclean) and unclean is not None:
          return unclean
      return bleach.clean(unclean, strip=True, tags=tags, attributes=[], styles=[])
  
  
  # TODO: Remove unescape_entities when mako html safe comes in
  def unescape_entities(value, safe=None):
      """
      Convert HTML-encoded data (stored in the database) to literal characters.
  
      Intended primarily for endpoints consumed by frameworks that handle their own escaping (eg Knockout)
  
      :param value: A string, dict, or list
      :param safe: A dict of escape sequences and characters that can be used to extend the set of
          characters that this function will unescape. Use with caution as there are few cases in which
          there will be reason to unescape characters beyond '&'.
      :return: A string or list or dict without html escape characters
      """
      safe_characters = {
          '&amp;': '&',
      }
  
      if safe and isinstance(safe, dict):
          safe_characters.update(safe)
  
      if isinstance(value, dict):
          return {
              key: unescape_entities(value, safe=safe_characters)
              for (key, value) in value.iteritems()
          }
  
      if is_iterable_but_not_string(value):
          return [
              unescape_entities(each, safe=safe_characters)
              for each in value
          ]
      if isinstance(value, basestring):
          for escape_sequence, character in safe_characters.items():
              value = value.replace(escape_sequence, character)
          return value
      return value
  
  
  def safe_json(value):
      """
      Dump a string to JSON in a manner that can be used for JS strings in mako templates.
  
      Providing additional forward-slash escaping to prevent injection of closing markup in strings. See:
       http://benalpert.com/2012/08/03/preventing-xss-json.html
  
      :param value: A string to be converted
      :return: A JSON-formatted string that explicitly escapes forward slashes when needed
      """
      return json.dumps(value).replace('</', '<\\/')  # Fix injection of closing markup in strings
  
new_contents: import json
  import collections
  
  import bleach
  
  
  def is_iterable(obj):
      return isinstance(obj, collections.Iterable)
  
  
  def is_iterable_but_not_string(obj):
      """Return True if ``obj`` is an iterable object that isn't a string."""
      return (is_iterable(obj) and not hasattr(obj, 'strip'))
  
  
  def strip_html(unclean, tags=None):
      """Sanitize a string, removing (as opposed to escaping) HTML tags
  
      :param unclean: A string to be stripped of HTML tags
  
      :return: stripped string
      :rtype: str
      """
      if not tags:
          tags = []
  
      if unclean is None:
          return u''
      elif isinstance(unclean, dict) or isinstance(unclean, list):
          return bleach.clean(str(unclean), strip=True, tags=[], attributes=[], styles=[])
      # We make this noop for non-string, non-collection inputs so this function can be used with higher-order
      # functions, such as rapply (recursively applies a function to collections)
      # If it's not a string and not an iterable (string, list, dict, return unclean)
      elif not isinstance(unclean, basestring) and not is_iterable(unclean):
          return unclean
      else:
          return bleach.clean(unclean, strip=True, tags=tags, attributes=[], styles=[])
  
  
  # TODO: Remove unescape_entities when mako html safe comes in
  def unescape_entities(value, safe=None):
      """
      Convert HTML-encoded data (stored in the database) to literal characters.
  
      Intended primarily for endpoints consumed by frameworks that handle their own escaping (eg Knockout)
  
      :param value: A string, dict, or list
      :param safe: A dict of escape sequences and characters that can be used to extend the set of
          characters that this function will unescape. Use with caution as there are few cases in which
          there will be reason to unescape characters beyond '&'.
      :return: A string or list or dict without html escape characters
      """
      safe_characters = {
          '&amp;': '&',
      }
  
      if safe and isinstance(safe, dict):
          safe_characters.update(safe)
  
      if isinstance(value, dict):
          return {
              key: unescape_entities(value, safe=safe_characters)
              for (key, value) in value.iteritems()
          }
  
      if is_iterable_but_not_string(value):
          return [
              unescape_entities(each, safe=safe_characters)
              for each in value
          ]
      if isinstance(value, basestring):
          for escape_sequence, character in safe_characters.items():
              value = value.replace(escape_sequence, character)
          return value
      return value
  
  
  def safe_json(value):
      """
      Dump a string to JSON in a manner that can be used for JS strings in mako templates.
  
      Providing additional forward-slash escaping to prevent injection of closing markup in strings. See:
       http://benalpert.com/2012/08/03/preventing-xss-json.html
  
      :param value: A string to be converted
      :return: A JSON-formatted string that explicitly escapes forward slashes when needed
      """
      return json.dumps(value).replace('</', '<\\/')  # Fix injection of closing markup in strings
  
subject: Fix move of strip html method updated with new bleach