# File lib/rubygems/specification.rb, line 788
  def validate
    extend Gem::UserInteraction
    normalize

    if rubygems_version != Gem::RubyGemsVersion then
      raise Gem::InvalidSpecificationException,
            "expected RubyGems version #{Gem::RubyGemsVersion}, was #{rubygems_version}"
    end

    @@required_attributes.each do |symbol|
      unless self.send symbol then
        raise Gem::InvalidSpecificationException,
              "missing value for attribute #{symbol}"
      end
    end

    unless String === name then
      raise Gem::InvalidSpecificationException,
            "invalid value for attribute name: \"#{name.inspect}\""
    end

    if require_paths.empty? then
      raise Gem::InvalidSpecificationException,
            'specification must have at least one require_path'
    end

    @files.delete_if            do |file| File.directory? file end
    @test_files.delete_if       do |file| File.directory? file end
    @executables.delete_if      do |file|
      File.directory? File.join(bindir, file)
    end
    @extra_rdoc_files.delete_if do |file| File.directory? file end
    @extensions.delete_if       do |file| File.directory? file end

    non_files = files.select do |file|
      !File.file? file
    end

    unless non_files.empty? then
      non_files = non_files.map { |file| file.inspect }
      raise Gem::InvalidSpecificationException,
            "[#{non_files.join ", "}] are not files"
    end

    unless specification_version.is_a?(Fixnum)
      raise Gem::InvalidSpecificationException,
            'specification_version must be a Fixnum (did you mean version?)'
    end

    case platform
    when Gem::Platform, Gem::Platform::RUBY then # ok
    else
      raise Gem::InvalidSpecificationException,
            "invalid platform #{platform.inspect}, see Gem::Platform"
    end

    unless Array === authors and
           authors.all? { |author| String === author } then
      raise Gem::InvalidSpecificationException,
            'authors must be Array of Strings'
    end

    licenses.each { |license|
      if license.length > 64
        raise Gem::InvalidSpecificationException,
          "each license must be 64 characters or less"
      end
    }

    # reject FIXME and TODO

    unless authors.grep(/FIXME|TODO/).empty? then
      raise Gem::InvalidSpecificationException,
            '"FIXME" or "TODO" is not an author'
    end

    unless Array(email).grep(/FIXME|TODO/).empty? then
      raise Gem::InvalidSpecificationException,
            '"FIXME" or "TODO" is not an email address'
    end

    if description =~ /FIXME|TODO/ then
      raise Gem::InvalidSpecificationException,
            '"FIXME" or "TODO" is not a description'
    end

    if summary =~ /FIXME|TODO/ then
      raise Gem::InvalidSpecificationException,
            '"FIXME" or "TODO" is not a summary'
    end

    if homepage and not homepage.empty? and
       homepage !~ /\A[a-z][a-z\d+.-]*:/i then
      raise Gem::InvalidSpecificationException,
            "\"#{homepage}\" is not a URI"
    end

    # Warnings

    %w[author description email homepage rubyforge_project summary].each do |attribute|
      value = self.send attribute
      alert_warning "no #{attribute} specified" if value.nil? or value.empty?
    end

    if summary and not summary.empty? and description == summary then
      alert_warning 'description and summary are identical'
    end

    alert_warning "deprecated autorequire specified" if autorequire

    executables.each do |executable|
      executable_path = File.join bindir, executable
      shebang = File.read(executable_path, 2) == '#!'

      alert_warning "#{executable_path} is missing #! line" unless shebang
    end

    true
  end