ColdFusion Muse

Henry II on Vacation - Why Teams Matter

Mark Kruger July 27, 2022 12:26 PM Business Of Development Comments (0)

There are thousands of applications built by one brilliant programmer. It plays out like this: Bob, the founder of Acme, has a great app idea. He hires "a computer guy" - that's how my mom describes me, a guy who "works with computers" like I was an employee at Best Buy. This "computer guy" is fantastic. Let's call him Henry II because I just watched "The Lion in Winter" and Peter O'Toole and Katherine Hepburn are soooo good together. Where was I? Oh yes, Peter... er... Henry is a guru-level programmer. He thinks along with Bob and builds to spec. He partners with Bob - the idea guy - to help the product succeed. The product grows and becomes wildly successful. In short order, it is obvious to Bob and Henry that the application needs more help than Henry can provide. So they set out to build a supporting cast of developers around Henry to share the load. This scenario plays out thousands of times every year all over the world. A superstar needs help and help is hired. And that is where our real drama begins...

Read More
  • Share:

Henry II on Vacation - Why Teams Matter

Mark Kruger March 15, 2018 12:23 PM Business Of Development Comments (2)

"Just add more resources..." is a comment I hear quite frequently in our corner of the tech world. It is often thought of as an easy "solution" to IT challenges. Unfortunately, adding additional developers can often result in further bottlenecks. The following is a real life example (the names have been changed to protect the innocent)!

Let's talk about Lead developer Henry II and his role within ACME Company. In spite of being obsessed over ownership of the Aquitaine and looking vaguely like Peter O'toole, he's a terrific programmer, smart, aggressive and a problem solver of the first order. He tackles tasks with a great deal of energy and seems to be able to see the whole picture. Were he the only programmer (a team of one) these qualities would serve him well to get the most out of what he has to offer. As it is, these qualities combine with ACME's development model to serve as a constraint to efficiencies of the team.

Henry, due to his sense of ownership and responsibility, does what needs to be done. He wraps his arms around tasks that demand attention, sometimes without differentiating between effective and ineffective use of his valuable time. He spends too much time working "within" the projects and and not enough time working "on" them – meaning the strategy and direction and planning and mentoring (the stuff a lead usually does) – where his domain knowledge is the most valuable. A quick illustration might be helpful.

ACME has a process that synchronizes files from a watched directory on an internal share out to the servers at the NOC. The process allows customer service to get new content onto the server by simply dropping a file in a local directory. Periodically one of the several dozen directories has a problem. A file to be synched "hangs" and is not copied over. No one knows why, but it is always a file in the same directory. The fix is to log into the synchronization software and reset it. This kick starts the synch and the file is then copied.

While Henry was touring one of his estates in the low countries this problem re-occurred. A ticket was written and a developer (doubling as Sys-Admin) looked at it but could not readily ascertain what was happening or find a way to fix it. The result was a note back to customer service that this task would have to wait till Henry the Armada returned from Denmark.

This event is not an isolated sort of event – Henry getting called in to save the day because he knows all of the who, what, when and how. So let's note a few things at work here in the aftermath.

Wrong Resource? The first question is probably, "why is a software programmer troubleshooting file synchronization?" There is a case where that is necessary – usually when a team is too tiny to have a lead at all. That's not the case here so, is this the best use of a key resource?

Documented Process? Is there a place where developers can go and search for troubleshooting tips on the synch process? This was not a new problem, it occurs periodically. The fix should be routine and documented so that anyone tasked with support, even a developer, could resolve the issue. By the second time someone had to fix this he or she should have opened a wiki page for "server content file synchronization" and added a header called "troubleshooting" along with mitigation steps.

Troubleshooting Ownership? If this had been one of my team members who bailed until "Henry comes back from hunting grouse" I would have questions – and not just "what in the ham sandwich is a grouse?" This is not the sort of problem that has the potential to bring down the server or cause other problems down the road – i.e. it's a manageable, solvable problem with the knowledge at hand, even if you know nothing about the synching process. For example, a developer or sys-admin could copy the file directly to the server.

This brings to mind a third related question. Why are the developers tasked with support bailing on such a simple issue? There are probably two reasons.

  • Empowerment – They did not feel empowered to resolve the issue. Perhaps they feared being locked in the Tower of London if their solution was not the one Henry endorsed. If this is the case then some mentoring is in order and some rethinking about roles.
  • Passivity and intransigence – in large applications developers "get away" with punting. Software is a black box to most end users and developers can narrow their focus down to just the tasks they most enjoy or that they are the most comfortable with. In those situations and given a superstar resource (Henry) who knows and does everything that needs to be done through his own high level sense of responsibility, developers do not reflect the same urgency of end users on bugs and service issues – knowing it will be resolved without holding them to account. Note – this matters if you are going to have your developers supporting end users. They have to adopt urgency and take ownership of an issue.

Also note that Henry's role (and personality) serve as an enabler for this to occur. As long as he's the repository of knowledge and the chief fixer we can't resolve this problem. Fixes, routines, process idiosyncrasies and procedures belong to institutional knowledge, not individual knowledge. His role actually makes him a bottleneck for work and support rather than shortening the time to fix and deploy things. His developers are less productive than they could be because he is so good at his job.

I call this team model the "superstar programmer". One guy is head and shoulders above everyone else, knows more, does more and everyone orbits around him. He does everything with excellence and alacrity but has so much on his plate that his speed and knowledge are self-defeating.

Teams matter. To get the most out of them they have to be organized around both talent and personal growth. Henry is doing too many things and especially too many trivial operational things that could be done by anyone. Those operational things need to be documented.

Let's discuss team productivity. Many people are surprised at the math of team development. If I can gain 150 hours of development, per month, from a single developer I should, theoretically, be able to get 300 hours per month out of 2 developers, 450 hours out of 4 etc. Reality doesn't work that way. A team is a network of individuals who work toward goals together. They must interact so as not to overlap. They have to meet and plan. You may not be able to divide the work up into discreet 150-hour chunks. With each new team member this problem is exacerbated as new connections, meetings, planning and divisions are made. So, a team of 5 developers may be 60 or 75 percent as effective as a team of 1 or 2. At some point economies of scale kick in and the productivity curve levels off. But the pattern resembles this chart.

Note that this inefficiency is a healthy curve. If you have done well at building your team you can expect this reduced level of productivity as the best possible outcome.

But what happens when have a rock star model? At 3 developers your rock star is managing the tasks and responsibility of his own work plus 2. At 4 developers the problem is at a breaking point. The curve dips down. There is not enough supporting work to divide up among the secondary developers. The rock star takes on more and more of the mission critical work himself. Support tasks and management tasks build up and your major talent becomes a fireman. His whole world is putting out fires all day long and he is behind the curve on each project and task trying to juggle assignments while he's still doing what he's always done.

The Fix

This is why teams and institutional organization really matter. Evolution is fine for birds but software developers tend to propagate mutations that are less rather than more beneficial. Make sure knowledge is systemetized and institutional. Don't be seduced by the superstar. To get the most out of her or him you will need to build a well supported system - otherwise she will fly off the rails as you allow her to take ownserhip of everything. Finally, prioritize between the urgent and the important. If you do have a superstar, chances are your best use of his talents will be at a higher level than troubleshooting operational issues - unless he's a sys-admin at heart (in which case hang on to him like grim death).

  • Share:

Up to $1000 Referral Fee!!

Mark Kruger July 14, 2017 12:48 PM Business Of Development Comments (0)

CF Webtools has revamped its awesome referral program to make it awesomer - or even more awesome. As you may know we have been offering generous referral bonuses to developers for years. If you bring us business we try and reward you. In 2016 CF Webtools paid out nearly $100,000 in referral bonuses! But our old program was hard to understand so our marketing guy - Curt - has twisted my arm to make better.

Here's the Deal

If you bring us business you get $500.00. Any business. A mom and pop store, someone selling pet insurance, an app for measuring dog poo by volume and color - we don't care. If it's business and we make a sale, you get $500. But wait there's more. If said business turns into at least 150 hours you get an additional $500! So, you can make $1000 just by name dropping.

The Part Curt Doesn't Like

Now I will have to avoid Curt for a few days after I say this, but if you bring us a whale - a customer with regular work involving at least half a developer (hopefully the top half) I will be even generouser - or even more generous. Call me and we'll make a deal. I promise we'll make it worth your while.

CF Webtools Pledge

So, your grandma is selling needle point online and you want to refer her to us but you are afraid. Maybe you fear we will treat her poorly, or that we won't take "needlinggrandma.com" seriously. Be reassured by the following Muse Pledge to you:

We will Reward You.

We will Make you Proud.

We will not Embarrass you.

We want to make you happy you turned over work to us. We will make every effort to insure it is a good experience.

What sort of thing qualifies?

CF Webtools has a large and diverse staff. Don't assume we won't be interested just because we shout "ColdFusion" all the time. We have a dedicated operations group for managing large technology stacks. We do IOS and Droid development. We manage complex databases and are familiar with many different environments. Give us a call and find out.

It's complicated

Ok, so you have a problem client or former employer where you had a bad experience. We get that. From month to month we are often embroiled in handling a "hand off" from a developer or company where things went south. We specialize in working hard to smooth things out for the customer and we do it without throwing the former developer under the bus. We will concentrate on the work and do our best to make you look good. If you don't want us to mention your name we won't. If it will help and you say it's ok we will. You will find us easy, dare I say charming to work with.

How do I make it happen?

  • Call Curt Lovegren at (402) 408-3733 ext 104 or...
  • Email your lead with as much information as you wish to cfleads@cfwebtools.com.
Before we call or email your lead we will contact you via email (or phone or carrier pigeon, whatever you prefer) and discuss the details and how to move forward. Our approach can involve you directly or we can leave you out of it - it's totally up to you.

We'll look to glean any information that can help us be of benefit to the prospective customer. Just reach out and let our staff do the rest. Easy, right?

  • Share:

Customers and how they Contribute to Estimating Angst

Mark Kruger July 10, 2017 5:04 PM Business Of Development Comments (1)

This is the moment the developers have been waiting for. After having thrown both the developer and his application under the bus, we are going to make room under there for the customer. Now if you are customer reading this, take heart. While I'm going to say some things that will hurt, in the end I'm going to rub salve on the wound and we will all sing Kumbaya together. Here we go.

The Muse finally has a number - a project that we've estimated at 350 hours. Of course, this estimate is not correct. Why? Because no estimate is ever correct. Please refer back to the first post in this series. The majority of estimates are wild guesses. We've done our best to find out all we can about the system, requirements, priorities and every little nitpicky detail we can imagine. Our estimate is based on that discovery. If all of our dozens of assumptions are correct then our estimate is rock solid. But of course, there are still things we don't know and many of our assumptions are simply off. Much of what we need to know we simply can't know until we dig in and start doing the work. For that reason we will give Bob a range of hours - say 275 to 375 hours - and dozens of caveats that he will epically fail to hear and absorb. What he will hear is the number 275 and that will be the basis of his expectations.

Let's check in with the Muse and Bob as they finalize the project.

  • Muse: Well Bob, as you can see by the painstakingly detailed 13 page document in front of you, we estimate 275 to 375 hours. Have you read the document?
  • Bob: I read... I got to page 2... uh... I did see the estimate at the end. So, 275 hours?
  • Muse: [caveat 1] 275 hours to 375 hours. You can expect it to be somewhere in the middle.
  • Bob: 275 eh? Wow that's a lot. But I get everything I asked for?
  • Muse:[caveat 2] To be clear you get everything we have carefully outlined and detailed in the proposal. If it's not in the proposal it would be "out of scope" - not included in this estimate.
  • Bob: Well, I can probably swing 275 as long as I can have it in 6 weeks.
  • Muse: [caveat 3] Well the timeline depends on resources and other factors. This is probably a one-woman job. It will take her around 4-5 weeks to do the core programming, then QA, revisions etc. You are probably looking at 8 to 10 weeks. [Caveat 1 again] It's 275 to 375 hours not including out of scope items that tend to arise.
  • Bob: Hmmm.... ok, I think we can do it. But just one thing. Did we discuss adding reporting to this application?
  • Muse: ...
  • Bob: Muse... you there? Did we lose our connection?
  • Muse: I'm here Bob... I was just asking my assistant to quickly remove sharp objects from my immediate vicinity. Now about your reporting...

Most clients are not quite as bad as Bob. Still, every contractor or development shop owner has a story remarkably similar to the one above. I know most Muse readers are developers. I can see you now in my mind's eye with righteous indignation and clenched fist saying, "You tell them muse, clients are the worst!" But actually, this is not their fault. Your customer has his or her own domain of knowledge. I have a customer who is a commodity trader. I expect him to know the difference between a bull call and a butterfly spread, but I do not expect him to know the difference between MySQL and MS SQL, how the cloud works, or why it takes 10 hours to program something. The basic issue is threefold:

  • Communication
  • Expectations
  • Cart and Horse problems
Today let's tackle the first two.

Read More
  • Share:

Developers, Can't Live With 'em, Can't Deprecate 'em

Mark Kruger June 20, 2017 11:20 AM Business Of Development Comments (0)

When last we checked in with Bob and the Muse (part 1 - applications) they were trying to come to grips with Bob's complex... I mean his application's complexity. We are now at the stage called "developer involvement" where he and the Muse are speaking with Sugar Sweet - the Muse's crack developer (and the name of a girl I dated in college). Let's go live to the conference call (be careful not to spook them).

  • Muse: Ok, we've outlined changes to the onboarding and broken it out into 3 programming tasks. Sugar will get us an estimate but it seems straightforward.
  • Sugar: Muse, a moment.
  • Muse: Sure what is it sweetie? (Don't judge me - it's her nickname so it's not harassment)
  • Sugar: I've taken a look at this application and the entire thing will need to be rewritten.
  • Bob: Wait what? That sounds expensive.
  • Sugar: I'm afraid we have no choice Bob. It's written in tags and the variable naming is all wrong. Plus the previous developers used... sorry, this is hard, I'm getting a little choked up... cfqueries instead of stored procedures. [small sob]
  • Muse: I'm going to step in here while Sugar get's a drink of water. We will work to retain as much of the legacy code as we can and focus only on security issues Bob. In other words we Won't refactor your code unless it's necessary to protect your investment. How does that sound.
  • Sugar: [sounding a little hurt] But the queries... and our best practice guide!
  • Muse: I think we can work with what we have here...
  • Sugar: This is so hard. I feel beet down. I'm not sure I cane work here anymore.

Developers come in all stripes and their views will greatly impact your estimate. Some of them have a religious devotion to certain technologies, libraries and approaches to development. To be a developer (at least on my staff) requires high aptitude, intelligence, breadth of knowledge and confidence. Those traits generate towering personalities like the Muse (whose lack of modesty is his only real flaw), and of course egos. They have opinions and they are usually not afraid to use them. Their defensive ferocity increases exponentially the closer you get to their favorite technology. If you don't believe me try yelling "Windows rules" at an IOS conference (and hope it's not an open carry state). For this reason, it's always a good idea to have non-developers involved in your estimates. Around here we call them project managers. They use their knowledge of the developer and the customer to "find the sweet spot" that meets the needs of the application and its stakeholders.

Muse Wisdom: Estimating is usually a joint effort.

Of course, not every estimate needs the once over by a project manager, but larger projects or enhancements should always be a collaboration. Developers need to be able to justify the estimates they provide to someone who knows them well enough to understand how they might get tripped up. Here are a few "types" of developer estimators.

The Refactorer

Sugar is in this camp. She will like over-estimate every task on older code because she sees any legacy code as debt that needs to be paid. To her this isn't optional, it's essential. In the real world it's definitely optional. Is script better than tags - in most cases yes (don't email me). Is using jQuery better than custom JS libraries? I believe it is. Are stored procs better than queries? Usually they are (though I've seen some god-awful stored procs). Best practices, frameworks, indentation, file naming conventions - these are all important parts of competent development. But when approaching legacy code there is a lot to consider. For example, has the customer managed to get a return on his initial investment? If he has, he may be ready for a rewrite. If not, we may need to work with what is there and not break the bank rewriting huge swaths of code. The business decisions rule the day. It's important for developers to understand the economics in play.

The Blithe Underestimator

Estimating is about imagining what could happen. What if the user doesn't check the box - what happens then? What happens when a user doesn't follow your pattern and puts in letters where numbers are indicated? Most developers react to these conditions with frustration. Who would do that? Why would a user use the application in that way when it's clearly designed to be used this way. A good estimator considers all these what-ifs. Estimating is also about accounting for what you still don't know. It's about challenging your assumptions. The underestimator concentrates on what he sees in front of him. His estimate comes with the caveat "if all my broad assumptions are correct". A good project manager will know the developer well enough to A) challenge him on his assumptions and B) add hours to the final estimate to insure it's adequate.

The Over-Complicator (Chicken Little)

Some developers are the opposite of the blithe underestimator. Instead of broad assumptions they build a huge list of unknowns and caveats. How do you know if you are an overcomplicator? Here's a little test for you. Let's say uou pull up Google and the page fails to load. Order the following list by probability.

  1. Google is down
  2. The entire internet is down
  3. It's the zombie apocalypse
  4. You've typed in "gloogle.com" accidently
  5. Your wireless connection is bad
  6. The network is under attack
  7. Your mom changed the wireless password again (for those you working in your basement)
  8. The NSA is monitoring your computer
  9. DNS is not responding
If anything but number 4, 5, 7 or 9 is near the top of your list you may be an over complicator.

Some time ago I was helping a Muse reader with an error via screen share. On the screen the error debug information had query code and indicated a malformed query. I asked what he had tried. "I tried a new DB driver, checked the network connection and I've been googling how cached execution plans work." I took a closer look at the debug output on the screen, highlighted a portion and said "You are missing a comma after this column." A good manager will know his devs well enough to spot an over estimator and adjust estimates accordingly.

The Technology Hammerer

Finally, there is the developer for whom everything is about tech. The saying goes that when your only tool is a hammer everything looks like a nail. Developers need to be reminded that what they are solving are behavior problems, not (typically) technical problems. When we build a new search engine for a company selling nuts and bolts, the problem we are solving is not faster indexing, better sorting, or more granular pattern matching. nope. It's the basic problem of folks rummaging through bins trying to figure out thread and length. We are trying to make that task easier.

The tech hammerer will turn to the technical aspects of a project over and over because that is her comfort zone. She will suggest products, approaches and solutions that may or may not solve the basic problem underlying the project.

Tech hammerers usually need to learn that it is highly beneficial to gather domain knowledge about your customer. What does the company do? How do they make money? (that's the most important question for a dev company like ours) What sort of problems do they solve with their application? These questions inform our decisions in ways that mere technical questions cannot. Moreover, they tend to make us better partners - better at suggesting changes that save or make money for the customer. "What if we chose to do it this way Bob, would that save your users a step? Do you really need this field, it seems like we have this covered with earlier data. Explain how this will help your user - I want to understand."

Conclusion

The main takeaway here is that developers and their personalities have an impact on your estimates. Estimating is a team effort and requires give and take from several sectors. In our next post we are going to throw customers under the bus - gently of course.

  • Share:

Why is Estimating So Dang Hard

Mark Kruger June 19, 2017 5:47 PM Business Of Development Comments (5)

Let's go Live to Bob and the Muse

Consider this typical interaction with a prospective customer:

  • Muse: Tell me what you need Bob.
  • Bob: I have an application hosted on ColdFusion 9. I want to upgrade to the latest version and move it to the cloud.
  • Muse: That's a good choice. The latest version of ColdFusion performs splendidly in the cloud and is much easier to manage. (yes the Muse uses words like "splendidly").
  • Bob: Great! How much will it cost me.
  • Muse: Well.... [lengthy pause]
  • Bob: Did I lose you? Muse... Hello...
  • Muse: Oh I'm here. I have some questions. What kind of application is it?
  • Bob: It's a customer portal where folks log in and use our whizzbang service.
  • Muse: Do you use any third party APIs?
  • Bob: Pbbbt... of course not.
  • Muse: Excellent - how about jar files. Do you remember using any jar files in your code to access Java stuff?
  • Bob: Jar files? What in the ham sandwich is a jar file?
  • Muse: It's a way you package Java classes. You might use it to do some complicated Java thing that ColdFusion can't handle on its own.
  • Bob: Uh... [Lengthy Pause]
  • Muse: Did I lose you? Bob... hello? Maybe we'll put a pin in that one.
  • Bob: Sorry my eyes just glazed over there for a second. Anyway, how much did you say?
  • Muse: Well I'm not sure I have enough information to uh...
  • Bob: Oh! and we also need to upgrade our thingy that posts reviews to Amazon and Yelp. Something about bees... apiary or something.
  • Muse: API Library maybe?
  • Bob: That's it!
  • Muse: [banging head on the desk] ok how about you walk me through the app.
  • Bob: Sure ... but... how much will it cost?

Now it's not the Muse's fault that he's having a hard time communicating. After all, if it was easy I'd be flipping burgers and still driving my '72 delta 88 from College. And before you get all up in Bob's grill, it's not his fault either. We IT natives tend to use lingo as if everyone has been exposed to the concept of an "API" or "java integration" or a "mouse".

So I'm going to let you in on a little secret. The bald truth is that development companies usually have no idea what something will cost even after you describe it to them thoroughly. The most accurate estimate for enhancements will always come from the original developer, and even then, they are often guessing wildly.

Muse Wisdom: Don't trust quick estimates or high levels of certainty!

Chances are if someone is throwing numbers around without asking a lot of questions and without being nervous about "guaranteeing" the cost, you are about to enter a relationship you will regret. Think Vegas chapel and too much bourbon and you'll get the idea. To help further the conversation about estimates I offer this 3-part blog series on "The hard task of estimating". My hope is that in the end, readers who are customers and readers who are developers will both come to understand a little more about this maddeningly ticklish task that we all must do.

Estimating is hard and estimates are often unreliable because of three main areas where issues arise:

  • Applications
  • Developers
  • Stakeholders or Customers
In this post we are going to talk about your application.

Read More
  • Share:

Business Referral - don't forget

Mark Kruger October 22, 2014 12:05 PM ColdFusion, Business Of Development Comments (0)

A week ago, in my post, The Muse Has Cash... I started a new program to reward community members for leads. Thank you for all the input and for the many leads generated already. We really appreciate it and we'll make you proud! After a quarter or so I will report on the success of the program.

Meanwhile, a few have pointed out that the previous post is lengthy so I wanted to put up the "express checkout" version. It's simple, if you refer a lead to us (email cfleads@cfwebtools.com) that results in new business, we will pay back to you 8% of the gross revenue from that customer in the first 10 months of working with the customer. If the customer spends 10k with us, you make $800.00. Simple and easy. So hook the Muse up. We are looking for another record year!

Note: In the past the Muse has offered bonuses for referring developers to us. This program is for new business, not developers - although as always if you are looking for work send me your resume. We typically hire several times a year.

  • Share:

The Muse has Cash and He's Not Afraid to Use It!

Mark Kruger October 7, 2014 11:58 AM Business Of Development, Job Openings Comments (0)

The hardest thing about running a ColdFusion development shop is getting in front of the people who might need your help. Thousands of companies could use the expertise we offer but it can be very difficult to approach them. In spite of our culture, our transparency, our chameleon-like flexibility, our unique reputation, our high competency and our focus on communication and productivity, CTO's and CIO's tend to lump CF Webtools in with the outsourcing crowd. That's just not who we are. The truth is, once we gain the ear of someone who needs us we have an amazing record at closing the deal and retaining the customer. We alleviate the pitfalls of ColdFusion (oh yes, there are pitfalls) and allow the benefits to shine. We simply bring too much to the table to ignore.

So that's the Gordian knot the Muse has been trying to unravel for the last 18 months or so as we have doubled and tripled in size. How do I get the name and reputation of my fantastic company in front of the folks who need us? I mean, besides a holocaust cloak ("...Then why wasn't it listed among our assets?") what do we have to work with? My executive team and I have spent a few weeks mulling this over and we have concluded that perhaps our greatest asset is our connection with developers within the ColdFusion Community.

The truth is that when a developer who has developed for a decision maker recommends us to that individual he or she is far more likely to listen and take our pitch seriously. After all, finding good ColdFusion talent is difficult. In our experience it is referrals that seal the deal. We began thinking, both the Muse and the CF Webtools staff tends to be engaged in user groups, forums, lists, and events focused on ColdFusion. Instead of dedicating a big chunk of money to a marketing budget (of dubious return) we had an epiphany. Why spend money on promotions and ads when the connection we need is right in front of our cfnose. Let's pay our friends in the community for their referrals.

The Big Plan

So our big plan is simple, we are going to generously reward any developer who refers a company to us that subsequently becomes a customer. The rules are simple. First, you need to be a part of the ColdFusion developer community. We are not looking to line the pockets of recruiters. But if you are in IT and work with ColdFusion you are a candidate. Finally your lead must result in a sale for you to get paid. In short, for forwarding a name to us you could get a check in the mail - that's it! Read on for the nitty gritty details.

Read More
  • Share: