Multiple changes in one go:
* Rename OAuth.Easy package to OAuth.Tokens.
* Parse JSON data in Twitter package.
* Add empty Follow_User procedure.
5 files changed, 72 insertions(+), 46 deletions(-)

M src/oauth-easy.adb => src/oauth-tokens.adb
M src/oauth-easy.ads => src/oauth-tokens.ads
M src/twit2.adb
M src/twitter.adb
M src/twitter.ads
M src/oauth-easy.adb => src/oauth-tokens.adb +16 -11
@@ 6,10 6,10 @@ with HMAC_SHA;
 with HTTP;
 with Hauki.Charbuf;
 
-package body OAuth.Easy is
+package body OAuth.Tokens is
    use Hauki;
    use Hauki.Charbuf;
-   
+
    function "+"(Str : String) return Unbounded_String
      renames To_Unbounded_String;
 

          
@@ 191,6 191,9 @@ package body OAuth.Easy is
             OAuth.Timestamp,
             To_String (Context.Key) & URL),
          Version      => "1.0");
+
+      Context.Request_Count := Context.Request_Count + 1;
+
       OAuth.Parameter_List.Append (Params, (Key => +"oauth_callback",
                                             Value => +"oob"));
 

          
@@ 225,11 228,13 @@ package body OAuth.Easy is
    end Request_Token;
 
    -- OAuth info for access token returned as header suitable for HTTP request
-   procedure As_Header (Context    : in out OAuth_Context;
-                        URL        : in     String;
-                        Method     : in     String;
-                        Parameters : in     OAuth.Parameter_List.List;
-                        Header     :    out Unbounded_String) is
+   procedure Access_Token_Header
+     (Context    : in out OAuth_Context;
+      URL        : in     String;
+      Method     : in     String;
+      Parameters : in     OAuth.Parameter_List.List;
+      Header     :    out Unbounded_String)
+   is
       Temp_Token : constant String := To_String (Context.Token);
       Temp_Secret : constant String := To_String (Context.Token_Secret);
       Params : OAuth.Parameter_List.List := Parameters;

          
@@ 249,12 254,12 @@ package body OAuth.Easy is
            (Natural'Image (Context.Request_Count),
             OAuth.Timestamp,
             To_String (Context.Key) & URL),
-         Version      => "1.0a");
+         Version      => "1.0");
       OAuth.Parameter_Sorting.Sort (OAuth_Params);
       OAuth.Parameter_Sorting.Sort (Params);
       OAuth.Parameter_Sorting.Merge (Target => Params, Source => OAuth_Params);
       Base_Str := +(OAuth.Create_Base_String (Method, URL, Params));
-      
+
       HMAC_SHA.Initialize
         (Key     => To_String (Context.Secret) & "&" & Temp_Secret,
          Context => Ctx);

          
@@ 269,6 274,6 @@ package body OAuth.Easy is
                                             Value => +""));
       OAuth.Parameter_Sorting.Sort (Params);
       Header := +(OAuth.Params_To_Header (Params));
-   end As_Header;
+   end Access_Token_Header;
 
-end OAuth.Easy;
+end OAuth.Tokens;

          
M src/oauth-easy.ads => src/oauth-tokens.ads +9 -8
@@ 2,7 2,7 @@ with Ada.Strings.Unbounded;
 
 use Ada.Strings.Unbounded;
 
-package OAuth.Easy is
+package OAuth.Tokens is
    type OAuth_Context is private;
 
    function Get_Token (Context : OAuth_Context) return Unbounded_String;

          
@@ 19,7 19,7 @@ package OAuth.Easy is
    procedure Init (Context         :    out OAuth_Context;
                    Consumer_Key    : in     String;
                    Consumer_Secret : in     String);
-   
+
    procedure Parse_Access_Token (Input   : String;
                                  Token   : out Unbounded_String;
                                  Secret  : out Unbounded_String;

          
@@ 30,11 30,12 @@ package OAuth.Easy is
                             URL          : in     String;
                             Method       : in     String);
 
-   procedure As_Header (Context    : in out OAuth_Context;
-                        URL        : in     String;
-                        Method     : in     String;
-                        Parameters : in     OAuth.Parameter_List.List;
-                        Header     :    out Unbounded_String);
+   procedure Access_Token_Header
+     (Context    : in out OAuth_Context;
+      URL        : in     String;
+      Method     : in     String;
+      Parameters : in     OAuth.Parameter_List.List;
+      Header     :    out Unbounded_String);
 
 private
    type OAuth_Context is record

          
@@ 44,4 45,4 @@ private
       Token_Secret  : Unbounded_String := Null_Unbounded_String;
       Request_Count : Natural   := 0;
    end record;
-end OAuth.Easy;
+end OAuth.Tokens;

          
M src/twit2.adb +3 -9
@@ 17,16 17,10 @@ with Hauki.Charbuf;
 procedure Twit2 is
    use Hauki;
    procedure Parse_JSON
-     (Input_Data: Charbuf.Char_Buffer; Data : out Tweet_List.List) is
+     (Input_Data: JSON.Data.JSON_Holder.Holder; Data : out Tweet_List.List) is
       S : Input.Unbounded_String_Stream;
    begin
-      Put_Line ("Parse_JSON begin: ");--  & Length (Input_Data)'Img);
-      Input.Open (S, Input_Data);
-      Put_Line ("Parse_Tweets");
-      Tweet_Parser.Parse_Tweets (S, Data);
-      Put_Line ("Input.Close");
-      Input.Close (S);
-      Put_Line ("Parse_JSON end");
+      Tweet_Parser.Create_Tweets (Input_Data, Data);
    end Parse_JSON;
 
    function Timestamp (T : Ada.Calendar.Day_Duration) return String is

          
@@ 73,7 67,7 @@ procedure Twit2 is
    Name : Unbounded_String;
    T : Twitter.Twitter_Type;
    PIN_URL : Unbounded_String;
-   Result : Charbuf.Char_Buffer;
+   Result : JSON.Data.JSON_Holder.Holder;
 
    Home_Tweets : Tweet_List.List;
 begin

          
M src/twitter.adb +34 -15
@@ 1,11 1,13 @@ 
 with Ada.Text_IO; use Ada.Text_IO;
 with Secrets;
+with Input;
 with OAuth;
-with OAuth.Easy;
+with OAuth.Tokens;
 with Properties;
 with HTTP;
 with URLs;
 with MBlog;
+with JSON.Parser;
 
 package body Twitter is
    use URLs;

          
@@ 22,12 24,12 @@ package body Twitter is
 
       if Length (Manager.My_Token) > 0
         and Length (Manager.My_Secret) > 0 then
-         OAuth.Easy.Init
+         OAuth.Tokens.Init
            (Context => Manager.C,
             Consumer_Key => Secrets.Get_Consumer_Key (Microblog),
             Consumer_Secret => Secrets.Get_Consumer_Secret (Microblog));
-         OAuth.Easy.Set_Token (Manager.C, To_String (Manager.My_Token));
-         OAuth.Easy.Set_Token_Secret
+         OAuth.Tokens.Set_Token (Manager.C, To_String (Manager.My_Token));
+         OAuth.Tokens.Set_Token_Secret
            (Manager.C, To_String (Manager.My_Secret));
       end if;
    end Init;

          
@@ 41,17 43,17 @@ package body Twitter is
    procedure Auth_Get_PIN_URL (Manager : in out Twitter_Type;
                                URL     : out Unbounded_String) is
    begin
-      OAuth.Easy.Init
+      OAuth.Tokens.Init
         (Context => Manager.C,
          Consumer_Key => Secrets.Get_Consumer_Key (Microblog),
          Consumer_Secret => Secrets.Get_Consumer_Secret (Microblog));
-      OAuth.Easy.Request_Token
+      OAuth.Tokens.Request_Token
         (Context => Manager.C,
          URL     => Request_Token_URL (Microblog),
          Method  => "GET");
       URL := To_Unbounded_String
         (OAuth_Token_URL (Microblog) & "?oauth_token="
-         & To_String (OAuth.Easy.Get_Token (Manager.C)));
+         & To_String (OAuth.Tokens.Get_Token (Manager.C)));
    end Auth_Get_PIN_URL;
 
    procedure Auth_Give_PIN (Manager : in out Twitter_Type;

          
@@ 70,7 72,7 @@ package body Twitter is
       OAuth.Parameter_List.Append
         (Extra_Params, (Key => To_Unbounded_String ("oauth_verifier"),
                         Value => To_Unbounded_String (PIN)));
-      OAuth.Easy.As_Header
+      OAuth.Tokens.Access_Token_Header
         (Context  => Manager.C,
          URL      => Access_Token_URL (Microblog),
          Method   => "GET",

          
@@ 83,20 85,20 @@ package body Twitter is
          Contents      => Result,
          Response_Code => R_Code);
       Put_Line ("Access_Token: " & Charbuf.To_String (Result));
-      OAuth.Easy.Parse_Access_Token
+      OAuth.Tokens.Parse_Access_Token
         (Input => Charbuf.To_String (Result),
          Token => Token,
          Secret => Token_Secret,
          User_Id => User_Id,
          Name => Name);
-      OAuth.Easy.Set_Token (Manager.C, To_String (Token));
-      OAuth.Easy.Set_Token_Secret (Manager.C, To_String (Token_Secret));
+      OAuth.Tokens.Set_Token (Manager.C, To_String (Token));
+      OAuth.Tokens.Set_Token_Secret (Manager.C, To_String (Token_Secret));
       Secrets.Set_Token (Microblog, To_String (Token));
       Secrets.Set_Token_Secret (Microblog, To_String (Token_Secret));
    end Auth_Give_PIN;
 
    procedure Homeline (Manager : in out Twitter_Type;
-                       Tweets  : out Charbuf.Char_Buffer) is
+                       Tweets  : out JSON.Data.JSON_Holder.Holder) is
       use OAuth;
 
       Home_URL : constant String := Home_Timeline_URL (Microblog);

          
@@ 105,7 107,8 @@ package body Twitter is
       Result : Charbuf.Char_Buffer;
       R_Code : Long_Integer;
    begin
-      Easy.As_Header (Manager.C, Home_URL, "GET", Extra_Params, OAuth_Header);
+      Tokens.Access_Token_Header
+        (Manager.C, Home_URL, "GET", Extra_Params, OAuth_Header);
       Put_Line ("Header: " & To_String (OAuth_Header));
       HTTP.Get_Page
         (URL => Home_URL,

          
@@ 114,7 117,17 @@ package body Twitter is
          Contents => Result,
          Response_Code => R_Code);
       if R_Code = 200 then
-         Tweets := Result;
+         declare
+            S : Input.Unbounded_String_Stream;
+         begin
+            Input.Open (S, Result);
+            JSON.Parser.Parse (S, Tweets);
+            Input.Close (S);
+         exception
+            when JSON.Parser.Parse_Error =>
+               Input.Close (S);
+               raise Invalid_JSON_Data_Error;
+         end;
       else
          -- Tweets := To_Unbounded_String ("error");
          Put_Line ("Error: " & Long_Integer'Image (R_Code));

          
@@ 136,7 149,7 @@ package body Twitter is
       Parameter_List.Append (Extra_Params,
         (To_Unbounded_String ("status"),
           To_Unbounded_String (Message)));
-      Easy.As_Header
+      Tokens.Access_Token_Header
         (Manager.C, Update_Address, "POST", Extra_Params, OAuth_Header);
       Put_Line ("Header: " & To_String (OAuth_Header));
       HTTP.Post_Page

          
@@ 152,4 165,10 @@ package body Twitter is
          raise Unknown_Error;
       end if;
    end Update;
+
+   procedure Follow_User (Manager : in out Twitter_Type;
+                          User_Id :        User_Id_Type) is
+   begin
+      null;
+   end Follow_User;
 end Twitter;

          
M src/twitter.ads +10 -3
@@ 1,6 1,7 @@ 
 with Ada.Strings.Unbounded;
-with OAuth.Easy;
+with OAuth.Tokens;
 with Hauki.Charbuf;
+with JSON.Data;
 
 use Ada.Strings.Unbounded;
 

          
@@ 9,9 10,12 @@ package Twitter is
 
    Authorization_Error : exception;
    Unknown_Error : exception;
+   Invalid_JSON_Data_Error : exception;
 
    type Twitter_Type is private;
 
+   subtype User_Id_Type is Long_Integer;
+
    procedure Init (Manager : out Twitter_Type);
 
    function Is_Authorized (Manager : Twitter_Type) return Boolean;

          
@@ 25,13 29,16 @@ package Twitter is
                             Name    : in out Unbounded_String);
 
    procedure Homeline (Manager : in out Twitter_Type;
-                       Tweets  : out Charbuf.Char_Buffer);
+                       Tweets  : out JSON.Data.JSON_Holder.Holder);
 
    procedure Update (Manager : in out Twitter_Type;
                      Message :        String);
+
+   procedure Follow_User (Manager : in out Twitter_Type;
+                          User_Id :        User_Id_Type);
 private
    type Twitter_Type is record
-      C : OAuth.Easy.OAuth_Context;
+      C : OAuth.Tokens.OAuth_Context;
       My_Token : Unbounded_String;
       My_Secret : Unbounded_String;
    end record;