# A model represents a fragment of the state of our sieve, specifically some subset
  # of the primes discovered so far.
  class Model < UntypedActor

    def initialize
      @primes = []
    end

    def onReceive(msg)
      # It's times like this that one really does miss Scala's pattern matching
      # but case fills in nicely enough
      case msg[0]
      when :add
        if msg.length != 2
          return
        end
        @primes << msg[1]
      when :prime?

        # Upfront validation; make sure we have some primes and that the message is of the appropriate size
        if msg.length != 2 || @primes.empty?
          self.getContext.replySafe nil
          return
        end

        # The model only considers a value prime if it doesn't equal or divide evenly into any previously 
        # observed prime.
        candidate = msg[1]
        resp = @primes.none? do |prime|
          candidate != prime and candidate % prime == 0
        end
        self.getContext.replySafe [resp ? :prime : :not_prime,candidate]
      else
        puts "Unknown message type #{type}"
      end
    end
  end