<div dir="ltr"><div class="gmail_default" style="font-size:small">Marcus</div><div class="gmail_default" style="font-size:small">   Take your time there is no compulsion to produce an example. It is a case of .... 'Hmmm this may be a good example, when I have time I "may" do one one day'.  I also think you should be demonstrating current best practice with the caveat that all tests pass. After all, we learn from the examples, and how else can you showcase new and great features of VTK?</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">Elvis, I agree with you here. However there is no point in a wholesale reworking of existing code to use new and great features of VTK. As these are examples for a broad audience, we should keep a wide variety of code until it actually fails. Then fix it.</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">Bill, do you have any views here?</div><div class="gmail_default" style="font-size:small"><br></div><div class="gmail_default" style="font-size:small">Regards</div><div class="gmail_default" style="font-size:small">   Andrew</div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, May 31, 2018 at 1:43 AM Elvis Stansvik <<a href="mailto:elvis.stansvik@orexplore.com">elvis.stansvik@orexplore.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div><div class="gmail_quote"><div dir="ltr">Den ons 30 maj 2018 17:07Marcus D. Hanwell <<a href="mailto:marcus.hanwell@kitware.com" target="_blank">marcus.hanwell@kitware.com</a>> skrev:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra">Hi Andrew,</div><div class="gmail_extra"><br></div><div class="gmail_extra">To the best of my knowledge the examples require backward compatibility, and so I couldn't show the "best" form for people who dislike calling .Get() until the minimum is bumped to VTK 8.1.0 I think. Most of my work is done on that, or even more recent SHAs, so I don't think about it too much.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Is there an answer for this, can we make an example that requires 8.1+, as we add more new features it seems like a reasonable request. I am really swamped right now, but was hoping to get to some charting examples too.</div></div></blockquote></div></div><div dir="auto"><br></div><div dir="auto">Speaking as an outsider, I think it would be fine if the examples dropped the requirement that they be backwards compatible, and only show the best practice with current stable release. It's what I see in most other projects I've used, and I think people accept that they'll have do do some work to get examples working with old releases.</div><div dir="auto"><br></div><div dir="auto">Others probably disagree though :)</div><div dir="auto"><br></div><div dir="auto">Elvis</div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><br></div><div class="gmail_extra">Thanks,</div><div class="gmail_extra"><br></div><div class="gmail_extra">Marcus<br>
<br><div class="gmail_quote">On Tue, May 29, 2018 at 6:39 PM, Andrew Maclean <span dir="ltr"><<a href="mailto:andrew.amaclean@gmail.com" rel="noreferrer" target="_blank">andrew.amaclean@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div style="font-size:small">Hi Marcus,</div><div style="font-size:small">   This is a very clear and succinct explanation of the usage of 

<div style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline">​</div><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">vtkNew<span> /

<div style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline">​</div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">vtkSmartPointer<span> /

<div style="font-size:small;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;display:inline">​</div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">vtkWeakPointer<span> .</span></span></span></span></span></span></div><div style="font-size:small"><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span>If you have time would it be possible to do a nice C++11 demonstration example to be added into VTK Examples?</span></span></span></span></span></span></div><div style="font-size:small"><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span>I have a suspicion that this will be an issue arising again and again.</span></span></span></span></span></span></div><div style="font-size:small"><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><br></span></span></span></span></span></span></div><div style="font-size:small"><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span>I'll be glad to help.</span></span></span></span></span></span></div><div style="font-size:small"><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><br></span></span></span></span></span></span></div><div><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">Personally (like Bill) I have never liked: <span style="text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline">.GetPointer()/.Get()<span>  in vtkNew so I haven't used it much. However ... since it implicitly returns the pointer now, I'll probably use it more.</span></span></span></span></span></div><div style="font-size:small"><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><br></span></span></span></span></span></span></div><div style="font-size:small"><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span>Rgeards</span></span></span></span></span></span></div><div style="font-size:small"><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span>   Andrew</span></span></span></span></span></span></div><div style="font-size:small"><span style="font-size:13px;background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><span style="background-color:rgb(255,255,255);text-decoration-style:initial;text-decoration-color:initial;float:none;display:inline"><span><br></span></span></span></span></span></span></div><br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="m_2615825143158934372m_3317224377328546736h5"><br><br><br>---------- Forwarded message ----------<br>From: "Marcus D. Hanwell" <<a href="mailto:marcus.hanwell@kitware.com" rel="noreferrer" target="_blank">marcus.hanwell@kitware.com</a>><br>To: Fcs <<a href="mailto:ftpronk@engits.com" rel="noreferrer" target="_blank">ftpronk@engits.com</a>><br>Cc: VTK Users <<a href="mailto:vtkusers@vtk.org" rel="noreferrer" target="_blank">vtkusers@vtk.org</a>><br>Bcc: <br>Date: Mon, 28 May 2018 10:12:24 -0400<br>Subject: Re: [vtkusers] Understanding vtkSmartPointers<br></div></div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div class="m_2615825143158934372m_3317224377328546736h5">On Mon, May 28, 2018 at 7:43 AM, Fcs <span dir="ltr"><<a href="mailto:ftpronk@engits.com" rel="noreferrer" target="_blank">ftpronk@engits.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Using VTK for one of our projects, we are encountering some memory leaks<br>
which, in time, cripple our system.  So I'm trying to have a better<br>
understanding of the  VTK pointers<br>
<<a href="https://blog.kitware.com/a-tour-of-vtk-pointer-classes/" rel="noreferrer noreferrer" target="_blank">https://blog.kitware.com/a-tour-of-vtk-pointer-classes/</a>>  . <br>
<br>
It was my (erroneous..?) belief that the *vtkSmartPointer*s would destroy<br>
the object they were holding when getting out of scope.  Carefully reading<br>
the kitware blog post linked hereinabove, and playing around with a test<br>
code (code sample below), I now understand that it is objects held by<br>
*vtkNew* that will be destroyed when out-of-scope, and that<br>
*vtkSmartPointer*s, on the contrary, will keep them alive as long as the<br>
reference count is non-zero.  Is this correct? <br></blockquote><div><br></div><div>No, that is not correct. The vtkNew class instantiates a vtkObject derived instance and will decrement its reference count when it goes out of scope. You can still store what was created by vtkNew in a vtkSmartPointer, increasing the reference count to two, and keeping that object alive even when the containing vtkNew goes out of scope.</div><div><br></div><div>In its simplest form, if you don't use other smart pointer classes with it then vtkNew acts much like a stack allocated object, where the object created is automatically deleted when it goes out of scope. You must remember that all vtkObject derived classes are implicitly reference counted - it is built into the API. The smart pointer classes just take care of incremementing/decrementing the reference count. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Now, from a practical point of view:  does this mean that I can, in a class,<br>
create an entire VTK pipeline with *vtkSmartPointer*s, and only store the<br>
latest object in a member variable to keep every object alive (So, in my<br>
code below, only bookkeep the object returned by applyFilters())?  And that<br>
when I'm finished, I can call ->Delete() on that object to clean-up the<br>
entire pipeline?  Is this a good practice?  Until now, I was painstakingly<br>
storing every object created for the lifetime of a pipeline, and I would<br>
like to know if I can simplify my code..<br>
<br></blockquote><div>In my opinion you should aim to never call Delete, but to have a smart pointer contain the things needed. I think all pipeline API will increase the reference count, and so you only usually need to keep a reference to the pipeline objects you are going to keep around/use. The debug leaks code will help you verify you got it right.</div><div><br></div><div>I would add that we have found in bigger applications that a passing debug leaks is not always enough, ensuring objects are deleted when they are done with is more difficult but necessary, especially in graphical applications that might run for some time. My honest summary of using the smart pointers (in classes, local code, etc) is:</div><div><br></div><div><div style="font-size:small;display:inline">​​</div>vtkNew - when you will instantiate the object, and want to keep a strong reference (you can't change what instance a vtkNew variable points to)</div><div><br></div><div><div style="font-size:small;display:inline">​​</div>vtkSmartPointer - when you might create, or use an instance passed in, and ensure it stays around for when you want to make calls. Assigning a different instance to one will decrement the one it points to before switching it to point to the new instance and incrementing.</div><div><br></div><div><div style="font-size:small;display:inline">​​</div>vtkWeakPointer - when you want to call API if something is still around, check for nullptr before using, will not affect reference count.</div><div><br></div></div></div><span><div>I think I wrote something similar back then. Whenever I see code like</div><div><br></div><div><div>vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();</div></div><div><br></div><div>I want to replace it with</div><div><br></div><div>vtkNew<vtkRenderer> renderer;</div><div><br></div></span><span><div>It does the exact same thing with no repetition, and is clearer. The examples require backwards compatibility with older VTK, and I don't think Bill liked calling .GetPointer()/.Get() on the vtkNew object. You no longer have to do that, but it is a more recent addition to the vtkNew API - it will implicitly return the pointer to the contained object as vtkSmartPointer does.</div><div><br></div></span><span><div>Hopefully this makes things a little clearer. At the end of the day all vtkObject derived classes (read most of the vtk* classes) are implicitly reference counted, the choice of vtkNew/vtkSmartPointer should be made depending upon how those instances will be used in your code - both will decrement the reference count by one when they go out of scope.</div><div><br></div><div>Marcus</div></span></div></div></div><span>
<br><br><br>---------- Forwarded message ----------<br>From: David Thompson <<a href="mailto:david.thompson@kitware.com" rel="noreferrer" target="_blank">david.thompson@kitware.com</a>><br>To: "Marcus D. Hanwell" <<a href="mailto:marcus.hanwell@kitware.com" rel="noreferrer" target="_blank">marcus.hanwell@kitware.com</a>><br>Cc: Fcs <<a href="mailto:ftpronk@engits.com" rel="noreferrer" target="_blank">ftpronk@engits.com</a>>, VTK Users <<a href="mailto:vtkusers@vtk.org" rel="noreferrer" target="_blank">vtkusers@vtk.org</a>><br>Bcc: <br>Date: Mon, 28 May 2018 10:30:06 -0400<br>Subject: Re: [vtkusers] Understanding vtkSmartPointers<br>> ...<br>
> I think I wrote something similar back then. Whenever I see code like<br>
> <br>
> vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();<br>
> <br>
> I want to replace it with<br>
> <br>
> vtkNew<vtkRenderer> renderer;<br>
<br>
With c++11, you can also say<br>
<br>
  auto renderer = vtkSmartPointer<vtkRenderer>::New();<br>
<br>
which cleans up the smart-pointer case a little bit.<br>
<br></span>
        David<div><div class="m_2615825143158934372m_3317224377328546736h5"><br>
<br><br><br>---------- Forwarded message ----------<br>From: "Marcus D. Hanwell" <<a href="mailto:marcus.hanwell@kitware.com" rel="noreferrer" target="_blank">marcus.hanwell@kitware.com</a>><br>To: David Thompson <<a href="mailto:david.thompson@kitware.com" rel="noreferrer" target="_blank">david.thompson@kitware.com</a>><br>Cc: Fcs <<a href="mailto:ftpronk@engits.com" rel="noreferrer" target="_blank">ftpronk@engits.com</a>>, VTK Users <<a href="mailto:vtkusers@vtk.org" rel="noreferrer" target="_blank">vtkusers@vtk.org</a>><br>Bcc: <br>Date: Mon, 28 May 2018 10:50:35 -0400<br>Subject: Re: [vtkusers] Understanding vtkSmartPointers<br><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, May 28, 2018 at 10:30 AM, David Thompson <span dir="ltr"><<a href="mailto:david.thompson@kitware.com" rel="noreferrer" target="_blank">david.thompson@kitware.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">> ...<br>
<span>> I think I wrote something similar back then. Whenever I see code like<br>
> <br>
> vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();<br>
> <br>
> I want to replace it with<br>
> <br>
> vtkNew<vtkRenderer> renderer;<br>
<br>
</span>With c++11, you can also say<br>
<br>
  auto renderer = vtkSmartPointer<vtkRenderer>::New();<br>
<br>
which cleans up the smart-pointer case a little bit.<br>
<span class="m_2615825143158934372m_3317224377328546736m_-6401836341026005623m_5778703222104742049HOEnZb"><font color="#888888"><br></font></span></blockquote><div>For sure, although in the case of class member variables it doesn't help, and I would argue vtkNew is cleaner (and vtkNew still uses far fewer characters, you got to preserve the finite resources on disk :P ). </div></div></div></div>
<br><br><br></div></div><span>---------- Forwarded message ----------<br>From: Fcs <<a href="mailto:ftpronk@engits.com" rel="noreferrer" target="_blank">ftpronk@engits.com</a>><br>To: <a href="mailto:vtkusers@vtk.org" rel="noreferrer" target="_blank">vtkusers@vtk.org</a><br>Cc: <br>Bcc: <br>Date: Mon, 28 May 2018 08:45:51 -0700 (MST)<br>Subject: Re: [vtkusers] Understanding vtkSmartPointers<br>Dear Mathieu, Marcus and David, thank you for your replies and tips, with a<br>
special thank to Marcus for his extensive explanations which really<br>
clarified a few of the subtleties of the VTK pointers.<br>
<br>
Marcus, I had few extra questions linked to your reply.<br>
<br>
<br></span><span>
> I In my opinion you should aim to never call Delete, but to have a smart<br>
> pointer contain the things needed. <br>
<br>
Is there any danger in calling Delete()? The case I had in mind was to<br>
perhaps free the memory occupied by a big structured/unstructured grid<br>
object which would need to live until a sub-grid is extracted from it.<br>
<br>
<br></span><span>
> I think all pipeline API will increase<br>
> the reference count, and so you only usually need to keep a reference to<br>
> the pipeline objects you are going to keep around/use. The debug leaks<br>
> code<br>
> will help you verify you got it right.<br>
<br>
How good is the guarantee that this will work? "I think" and "usually" seem<br>
to imply that my mileage might vary on this one.. :-)  Does it mean that<br>
this should work in general, but that perhaps some exotic or slightly buggy<br>
newer features might not behave correctly? The use case I'm trying to<br>
implement has a variable number of pre-definied filters which I'm chaining<br>
together. If I test all the possible combinations, and they work, do I have<br>
the guarantee they will always work?<br>
<br>
<br></span><span>
> I would add that we have found in bigger applications that a passing debug<br>
> leaks is not always enough, ensuring objects are deleted when they are<br>
> done with is more difficult but necessary, especially in graphical<br>
> applications that might run for some time. <br>
<br>
Does this not imply that every vtkObject created should be stored and<br>
deleted manually afterwards? Or are there other ways to detect living<br>
vtkObjects when you don't have a direct member variable pointing to it? <br>
(say, like the vtkPlane created in applyFilters() in my example code..)<br>
<br>
<br></span><span>
> It does the exact same thing with no repetition, and is clearer. The<br>
> examples require backwards compatibility with older VTK, and I don't think<br>
> Bill liked calling .GetPointer()/.Get() on the vtkNew object. You no<br>
> longer have to do that, but it is a more recent addition to the vtkNew API<br>
> - it will implicitly return the pointer to the contained object as<br>
> vtkSmartPointer does.<br>
<br>
Good to know! Starting from which version is the call to<br>
.GetPointer()/.Get() no longer needed? We are developing in vtk 6 at the<br>
moment, but we should update to a new version at some point in the near<br>
future.<br>
<br></span><span>
Kind regards,<br>
<br>
Francois.<br>
<br>
<br>
<br>
<br>
<br>
<br>
--<br>
Sent from: <a href="http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html" rel="noreferrer noreferrer" target="_blank">http://vtk.1045678.n5.nabble.com/VTK-Users-f1224199.html</a><br>
<br>
_______________________________________________<br>
Powered by <a href="http://www.kitware.com" rel="noreferrer noreferrer" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer noreferrer" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Please keep messages on-topic and check the VTK FAQ at: <a href="http://www.vtk.org/Wiki/VTK_FAQ" rel="noreferrer noreferrer" target="_blank">http://www.vtk.org/Wiki/VTK_FAQ</a><br>
<br>
Search the list archives at: <a href="http://markmail.org/search/?q=vtkusers" rel="noreferrer noreferrer" target="_blank">http://markmail.org/search/?q=vtkusers</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="https://vtk.org/mailman/listinfo/vtkusers" rel="noreferrer noreferrer" target="_blank">https://vtk.org/mailman/listinfo/vtkusers</a><br>
</span></blockquote></div><span class="m_2615825143158934372m_3317224377328546736HOEnZb"><font color="#888888"><br clear="all"><div><br></div>-- <br><div dir="ltr" class="m_2615825143158934372m_3317224377328546736m_-6401836341026005623gmail_signature" data-smartmail="gmail_signature">___________________________________________<br>Andrew J. P. Maclean<br><br>___________________________________________</div></font></span></div>
</blockquote></div><br></div></div>
_______________________________________________<br>
Powered by <a href="http://www.kitware.com" rel="noreferrer noreferrer" target="_blank">www.kitware.com</a><br>
<br>
Visit other Kitware open-source projects at <a href="http://www.kitware.com/opensource/opensource.html" rel="noreferrer noreferrer" target="_blank">http://www.kitware.com/opensource/opensource.html</a><br>
<br>
Please keep messages on-topic and check the VTK FAQ at: <a href="http://www.vtk.org/Wiki/VTK_FAQ" rel="noreferrer noreferrer" target="_blank">http://www.vtk.org/Wiki/VTK_FAQ</a><br>
<br>
Search the list archives at: <a href="http://markmail.org/search/?q=vtkusers" rel="noreferrer noreferrer" target="_blank">http://markmail.org/search/?q=vtkusers</a><br>
<br>
Follow this link to subscribe/unsubscribe:<br>
<a href="https://public.kitware.com/mailman/listinfo/vtkusers" rel="noreferrer noreferrer" target="_blank">https://public.kitware.com/mailman/listinfo/vtkusers</a><br>
</blockquote></div></div></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">___________________________________________<br>Andrew J. P. Maclean<br><br>___________________________________________</div>