Intersection Sphere::GetIntersection(const Ray& r)
{
    Ray r_obj(r.getTransformedCopy(this->transform.invT()));

    float radius = 0.5f;
    glm::vec3 center(0.f);

    float A = glm::length2(r_obj.direction);
    float B = 2 * (glm::dot(r_obj.direction, r_obj.origin - center));
    float C = glm::length2(r_obj.origin - center) - glm::pow(radius, 2.f);

    float disc = glm::pow(B, 2.f) - 4 * A * C;
    if (disc<0) return Intersection(); // B^2-4AC<0 then no intersection

    float t = ( -B + glm::sqrt(disc) ) / (2 * A);
    float temp = ( -B - glm::sqrt(disc) ) / (2 * A);
    if (t >= 0)
    {
        if (temp < t && temp >= 0) t = temp;
    }
    else
        t = temp;

    if (t < 0 ) return Intersection(); // not in the front

    glm::vec3 ipoint(r_obj.origin + t * r_obj.direction);
    glm::vec3 inormal(glm::normalize(ipoint - center));
    glm::vec3 itangent = glm::cross(glm::vec3(0,1,0), inormal);
    if (fequal(glm::length2(itangent), 0.f))
    {
        itangent = glm::vec3(0,0,1);
    }


    glm::vec3 ipoint_world(this->transform.T() * glm::vec4(ipoint, 1.f));

    glm::vec4 normal4_world(this->transform.invTransT() * glm::vec4(inormal,0.f));

    glm::vec3 normal_world( normal4_world );
    normal_world = glm::normalize(normal_world);

    glm::vec3 tangent_world = glm::normalize(glm::vec3(this->transform.invTransT() * glm::vec4(itangent, 0.f)));
    //bitangent computed in Intersection constructor

    float t_world = glm::dot(ipoint_world - r.origin, r.direction);

    glm::vec2 uv = this->GetUVCoordinates(ipoint);
    glm::vec3 s_color = Material::GetImageColorInterp(uv, this->material->texture);

    return Intersection(ipoint_world, normal_world, tangent_world, t_world, s_color, this);

}
Intersection SquarePlane::GetIntersection(const Ray& r)
{
    Ray r_obj(r.getTransformedCopy(this->transform.invT()));

    glm::vec3 center(0.f, 0.f, 0.f);
    glm::vec3 normal(0.f, 0.f, 1.f);
    float halfside = 1 * 0.5f;

    if (fequal(r_obj.direction.z, 0.f))
        return Intersection();

    // since it's a fixed XY plane, this is a simplified ray-plane intersection
    float t = (center.z - r_obj.origin.z) / r_obj.direction.z;

    if (t < 0) return Intersection();

    glm::vec3 ipoint(r_obj.origin + t * r_obj.direction);

    if (ipoint.x > center.x + halfside || ipoint.x < center.x - halfside)
        return Intersection();
    if (ipoint.y > center.y + halfside || ipoint.y < center.y - halfside)
        return Intersection();

    glm::vec3 ipoint_world(this->transform.T() * glm::vec4(ipoint, 1.f));
    glm::vec4 normal4_world(this->transform.invTransT() * glm::vec4(normal,0.f));

    glm::vec3 normal_world(normal4_world);
    normal_world = glm::normalize(normal_world);

    float t_world = glm::dot(ipoint_world - r.origin, r.direction);
    glm::vec3 s_color = Material::GetImageColorInterp(this->GetUVCoordinates(ipoint), this->material->texture);


    glm::vec4 tangent_o(1,0,0,0);
    glm::vec3 tangent_world = glm::normalize(glm::vec3(this->transform.invTransT() * tangent_o));
    //bitangent computed in Intersection constructor

    return Intersection(ipoint_world, normal_world, tangent_world, t_world, s_color, this);
}
    std::string
    Java_Compiler_Dump_Algorithm::process ( boost::uint32_t compiler_id,
					   std::string filename )
    {

#ifdef LIBREVERSE_DEBUG
      Trace::write_Trace ( TraceArea::GRNN_OPTIMIZER,
			   TraceLevel::DETAIL,
			   "Entering Java_Compiler_Dump_Algorithm::process" );
#endif /* LIBREVERSE_DEBUG */


      std::stringstream output;

      try
	{
	  reverse::io_types::File_ID::ptr_t file_obj ( new reverse::io::File_ID ( filename ) );
	    
	  reverse::java_module::Reader r_obj ( file_obj );
	    
	  r_obj.read_Class_Header();

	  reverse::data_types::memory_map::ptr_t mem_ptr = r_obj.get_memory_map();

	  output << boost::format("  <%1%>") % classifier::Java_Input_Tag_Names::TAG_FILE << std::endl;

	  output << boost::format ( "    <%1%>%2%</%3%>" )
	    % classifier::Java_Input_Tag_Names::TAG_TARGET_ID
	    % compiler_id
	    % classifier::Java_Input_Tag_Names::TAG_TARGET_ID << std::endl;

	  output << boost::format ( "    <%1%>%2%</%3%>" )
	    % classifier::Java_Input_Tag_Names::TAG_FILESIZE
	    % ( mem_ptr->size() )
	    % classifier::Java_Input_Tag_Names::TAG_FILESIZE << std::endl;

	  //   Get class header
	  reverse::java_types::Class_Header::ptr_t hdr_ptr = r_obj.get_Header();

	  //   Grab data
	  std::vector<float> stats(12,0);
	  collect_Constant_Pool_Stats ( stats, hdr_ptr->get_Constant_Pool_Begin(), hdr_ptr->get_Constant_Pool_End() );

	  //   Add entry to output file
	  output << boost::format ( "    <%1%>%2%.%3%</%4%>" )
	    % classifier::Java_Input_Tag_Names::TAG_VERSION
	    % hdr_ptr->get_Major_Version()
	    % hdr_ptr->get_Minor_Version()
	    % classifier::Java_Input_Tag_Names::TAG_VERSION << std::endl;

	  output << boost::format ( "    <%1%>%2%</%3%>" )
	    % classifier::Java_Input_Tag_Names::TAG_THIS_INDEX
	    % hdr_ptr->get_This_Class()
	    % classifier::Java_Input_Tag_Names::TAG_THIS_INDEX << std::endl;

	  output << boost::format ( "    <%1%>%2%</%3%>" )
	    % classifier::Java_Input_Tag_Names::TAG_SUPER_INDEX
	    % hdr_ptr->get_Super_Class()
	    % classifier::Java_Input_Tag_Names::TAG_SUPER_INDEX << std::endl;

	  output << boost::format ( "    <%1%>%2%</%3%>" )
	    % classifier::Java_Input_Tag_Names::TAG_CONSTANT_POOL_COUNT
	    % hdr_ptr->get_Constant_Pool_Count()
	    % classifier::Java_Input_Tag_Names::TAG_CONSTANT_POOL_COUNT << std::endl;

	  float constant_pool_total = hdr_ptr->get_Constant_Pool_Count();
	  print_Constant_Pool_Stats ( output, stats, constant_pool_total );

	  output << boost::format ( "    <%1%>%2%</%3%>" )
	    % classifier::Java_Input_Tag_Names::TAG_FIELD_COUNT
            % hdr_ptr->get_Field_Count()
	    % classifier::Java_Input_Tag_Names::TAG_FIELD_COUNT << std::endl;

	  output << boost::format ( "    <%1%>%2%</%3%>" )
	    % classifier::Java_Input_Tag_Names::TAG_METHOD_COUNT
            % hdr_ptr->get_Method_Count()
	    % classifier::Java_Input_Tag_Names::TAG_METHOD_COUNT << std::endl;

	  output << boost::format("  </%1%>" ) % classifier::Java_Input_Tag_Names::TAG_FILE << std::endl;
	}
      catch ( std::exception &e )
	{

#ifdef LIBREVERSE_DEBUG
	  Trace::write_Trace ( TraceArea::GRNN_OPTIMIZER,
			       TraceLevel::ERROR,
			       boost::str ( boost::format("(ERROR) Cannot read %1%. Skipping the file. ") % filename ) );

	  Trace::write_Trace ( TraceArea::GRNN_OPTIMIZER,
			       TraceLevel::ERROR,
			       e.what() );
#endif /* LIBREVERSE_DEBUG */

	}

#ifdef LIBREVERSE_DEBUG
      Trace::write_Trace ( TraceArea::GRNN_OPTIMIZER,
			   TraceLevel::DETAIL,
			   "Exiting Java_Compiler_Dump_Algorithm::process" );
#endif /* LIBREVERSE_DEBUG */


      return output.str();
    }