# File lib/automateit/shell_manager/portable.rb, line 210
  def cp(sources, target, opts={})
    # TODO ShellManager::Portable#cp -- rather funky, needs a code review
    fu_opts = _fileutils_opts
    for opt in [:noop, :verbose]
      opt = opt.to_sym
      fu_opts[opt] = opts[opt] if opts[opt]
    end

    fu_opts_with_preserve = fu_opts.clone
    fu_opts_with_preserve[:preserve] = \
      if opts[:preserve] == :try
        fsim = File::Stat.instance_methods
        (fsim.include?("uid") and fsim.include?("gid") and
         fsim.include?("mode") and fsim.include?("atime"))
      else
        opts[:preserve]
      end

    changed = []
    sources_a = [sources].flatten
    sources_a.each do |parent|
      Find.find(parent) do |child|
        source_fn = File.directory?(child) ? child+"/" : child
        target_dir = File.directory?(target)
        target_fn = peer_for(source_fn, target)

        log.debug(PNOTE+"comparing %s => %s" % [source_fn, target_fn])
        source_st = File.stat(source_fn)
        is_copy = false
        begin
          begin
            target_st = File.stat(target_fn)

            unless target_dir
              # Is the file obviously different?
              if source_st.file?
                for kind in %w(size mtime)
                  next if kind == "mtime" and ! opts[:preserve]
                  unless source_st.send(kind) == target_st.send(kind)
                    log.debug(PNOTE+"%s not same %s" % [target_fn, kind])
                    raise EOFError.new
                  end
                end

                unless FileUtils.identical?(source_fn, target_fn)
                  log.debug(PNOTE+"%s not identical" % target_fn)
                  raise EOFError.new
                end
              end

              # File just needs to be altered
              if opts[:preserve]
                unless source_st.mode == target_st.mode
                  changed << child
                  log.debug(PNOTE+"%s not same mode" % target_fn)
                  chmod(source_st.mode, target_fn, fu_opts)
                end
                unless source_st.uid == target_st.uid and source_st.gid == target_st.gid
                  changed << child
                  log.debug(PNOTE+"%s not same uid/gid" % target_fn)
                  chown(source_st.uid, source_st.gid, target_fn, fu_opts)
                end
              end
            end
          rescue EOFError
            changed << child
            is_copy = true
          end
        rescue Errno::ENOENT
          changed << child
          log.debug(PNOTE+"%s not present" % target_fn)
          is_copy = true
        end
        if is_copy
          log.info(PEXEC+"cp%s %s %s" % [opts[:recursive] ? ' -r' : '', source_fn, target_fn])
          ## puts "fo %s" % fu_opts.inspect
          ## puts "fowp %s" % fu_opts_with_preserve.inspect
          FileUtils.cp_r(source_fn, target_fn, fu_opts_with_preserve)
        end
      end
    end

    result = \
      if changed.empty?
        false
      else
        if sources_a.size == 1
          changed.first
        else
          changed.uniq
        end
      end
    return result
  end