with Text_Io;
package body Encapsulate is

    Shared : Composite;

    function Set_To (I : Integer) return Composite is
        Temp : Composite;
    begin
        for N in Index loop
            Temp (N) := I;
        end loop;

        return Temp;
    end Set_To;

    function Value_Of (C : Composite) return Integer is
    begin
        return C (Index'First);
    end Value_Of;

    -- for testing only; this allows the scheduler to overlap readers and
    -- writers and thus screw up if Readers_Writers doesn't do its job.
    -- it also checks that the copy is consistent.
    procedure Copy (From : in Composite; To : in out Composite) is
    begin
        for I in Index loop
            To (I) := From (I);
            -- delay so that another access could be made:
            delay 0.5;
        end loop;
        -- test for consistency:

        for I in Index range Index'Succ (Index'First) .. Index'Last loop
            if To (I) /= To (Index'First) then
                raise Program_Error;
            end if;
        end loop;
    end Copy;

    procedure Read_Put (Item : Composite) is
    begin
        Msg.Put (Integer'Image (Value_Of (Item)) & " read");
    end Read_Put;

    procedure Write_Put (Item : Composite) is
    begin
        Msg.Put (Integer'Image (Value_Of (Item)) & " written");
    end Write_Put;

    task body Msg is
    begin
        loop
            select
                accept Put (S : String) do
                    Text_Io.Put (S);
                    Text_Io.New_Line;
                end Put;
            or
                terminate;
            end select;
        end loop;
    end Msg;

    package Share is new Shared_Variable (Object_Type => Composite,
                                          Object => Shared,
                                          Read_Put => Read_Put,
                                          Write_Put => Write_Put,
                                          Copy => Copy);
    use Share;

    procedure Read (C : out Composite) is
        Temp : Composite;
    begin
        Share.Read (Temp);
        C := Temp;
    end Read;

    procedure Write (C : in Composite) is
    begin
        Share.Write (C);
    end Write;

begin

    Shared := Set_To (0);

end Encapsulate;
