# File lib/rhc/core_ext.rb, line 83
  def textwrap_ansi(limit, breakword=true)
    re = breakword ? /
      ( 
        # Match substrings that end in whitespace shorter than limit
        #{CHAR_SKIP_ANSI}{1,#{limit}} # up to limit
        (?:\s+|$)                     # require the limit to end on whitespace
        |
        # Match substrings equal to the limit
        #{CHAR_SKIP_ANSI}{1,#{limit}} 
      )
      /x :
      /
      ( 
        # Match substrings that end in whitespace shorter than limit
        #{CHAR_SKIP_ANSI}{1,#{limit}}
        (?:\s|$)                     # require the limit to end on whitespace
        |
        # Match all continguous whitespace strings
        #{CHAR_SKIP_ANSI}+?
        (?:\s|$)
        (?:\s+|$)?
      )
      /x
    escapes = []

    split("\n",-1).inject([]) do |a, line|
      if line.length < limit
        a << line 
      else
        line.scan(re) do |segment, other|
          if escapes.present? 
            a << escapes.map{ |s| "\e[#{s}"}.join
            a[-1] << segment.rstrip   
          else
            a << segment.rstrip
          end

          segment.scan(ANSI_ESCAPE_SEQUENCE).map{ |e| e.first }.each do |e|
            case e
            when '0m' then escapes.clear
            else escapes << e
            end
          end
          a[-1] << "\e[0m" if escapes.present?
        end
      end
      a
    end
  end

  def strip_ansi
    gsub(ANSI_ESCAPE_SEQUENCE, '')
  end
end

unless HTTP::Message.method_defined? :ok?
  #:nocov:
  class HTTP::Message
    def ok?
      HTTP::Status.successful?(status)
    end
  end
  #:nocov:
end

unless DateTime.method_defined? :to_time 
  #:nocov:
  class DateTime
    def to_time
      Time.parse(to_s)
    end
  end
  #:nocov:
end

#
# Allow http => https redirection, see 
# http://bugs.ruby-lang.org/issues/859 to 1.8.7 for rough
# outline of change.
#
module OpenURI
  def self.redirectable?(uri1, uri2) # :nodoc:
    # This test is intended to forbid a redirection from http://... to
    # file:///etc/passwd.
    # However this is ad hoc.  It should be extensible/configurable.
    uri1.scheme.downcase == uri2.scheme.downcase ||
    (/\A(?:http|ftp)\z/i =~ uri1.scheme && /\A(?:https?|ftp)\z/i =~ uri2.scheme)
  end
end

class Hash
  def stringify_keys!
    transform_keys!(:to_s)
  end
  def symbolize_keys!
    transform_keys!(:to_sym)
  end
  def slice!(*args)
    s = []
    args.inject([]) do |a, k|
      s << [k, delete(k)] if has_key?(k)
    end
    s
  end
  def slice(*args)
    args.inject({}) do |h, k|
      h[k] = self[k] if has_key?(k)
      h
    end
  end
  def reverse_merge!(other_hash)
    # right wins if there is no left
    merge!( other_hash ){|key,left,right| left }
  end
  protected
    def transform_keys!(operation)
      keys.each do |key|
        v = delete(key)
        if v.is_a? Hash
          v.transform_keys!(operation)
        elsif v.is_a? Array
          v.each{ |value| value.transform_keys!(operation) if value.is_a? Hash }
        end
        self[(key.send(operation) rescue key) || key] = v
      end
      self
    end
end