text:
Speak to an expert 0203 389 9786
Hilltop Manor
Login or Register to save your favourites
Home > Homestays > Hilltop Manor
OVERVIEW Features Gallery REGLAR EXPERIENCES RATES LOCATION Terms
Hilltop Manor has been featured in leading UK and EU design and architectural publications – Elle Decoration in the UK, Cote Maison in France, NYarum in Sweden and Residence NL in the Netherlands, Living Corriere in Italy. Discover why…….
Hilltop Manor is a magnificent and commanding home, standing regally in stunning grounds; a historical mansion with mountain views, refurbished to an exquisite finish and fine standards for an unparalleled experience nestled at the gateway to the Scottish Highlands.
The rather imposing exterior showcases a beautiful example of Edwardian architecture; built originally in 1909, Hilltop Manor offers all the trappings of a luxury, boutique hotel, with an immaculately and suavely finished design specification and an array of five-star style services for a flawlessly indulgent experience.
This retreat is set within a beautiful rural position, offering a sumptuous, yet cosy, escape from the bustle of urban living.
The interiors at Hilltop Manor are impeccably tasteful, offering impeccable quality, and display a zesty designer panache. A blend of modern-rustic and classic, this stylish home is chic, immaculately finished and oozes charismatic touches. From charcoal tones walls to oil paintings, large original open fireplaces and panelled wood walls, to enormous bay windows overlooking the silvery mountains, Hilltop Manor offers stunning proportions, impressive design choices and elegant interiors.
The magnanimously proportioned living room has an enormous, uber-chic mustard toned sofa as its centrepiece; accessorised with quality European designers and sophisticated dusty tones. Hilltop Manor merges historical architecture with sleek, contemporary, yet timeless, design.
The dining room is a masterpiece of solid, natural timber, with a stunning five and a half meter long table in bronze and oak, with a large capacity for twenty diners. This prestigious dining room nonetheless imbibes the natural designer ease of the home; an ideal space for catered events, celebrations, reunions and anniversaries, with world-class catering team on hand.
There is a second reception room which offers sultry and earthy tones, a snug-like ambience together with huge sofas a cosy open log fire.
Hilltop Manor can accommodate eighteen guests in nine uniquely designed bedrooms, each with a private en-suite bathroom. These rooms offer the last word in elegant, restorative and understated designer flair. Crisp and minimal, all the hallmarks of quality are present: Egyptian cotton bed linen, thick fluffy towels and top-range fittings such as sleek walk-in slate showers and free-standing designer baths.
The kitchen is a walnut and dark marble affair, offering state of the art fittings for large-scale dining; there is a natural flow between the spaces, framed with enormous windows and a finish that is unpretentious yet unparalleled in quality.
Hilltop Manor has grand proportions and effortlessly carries off an array of unique designer choices: beautiful antique carriage lighting, Scandinavian inspired four poster bed, bold colour choices and blends cutting-edge and timeless-classic furnishings.
When "downtime" beckons, there is a sombre-toned, ambient cinema room: a real hideaway, with Bose, surround sound system – ideal for rainy afternoons.
Hilltop Manor will delight aesthetes and interiors enthusiasts; the quality and execution of raw materials is unparalleled: slate, oak, stone, marble and walnut, whilst this home is infused with natural light and finished with an edgy and confident colour range.
This prestigious home is set within five and a half acres of private grounds. There is an expansive stone terrace with views across the Tay valley, leading to a perfect blend of formal gardens and beautiful wilderness for intriguing rambling. For a little touch of woodland indulgence, there is a wood-fired hot tub in the woods, large enough for eight. Guests can enjoy walks directly from the estate.
Hilltop Manor is a masterful example of contemporary design harmonising with traditional architecture; an exciting display of quality, designer flair and all the little extra touches of luxury that a guest would receive in a top-class hotel, set within a rugged and dynamic Highland landscape.
from £19,425 per week
Should coronavirus related travel restrictions mean your holiday cannot go ahead then simply request a change of dates. T&Cs apply
Enquire about Hilltop Manor
Mr Mrs Ms Other
Preferred arrival date *
Select: January 2021 Mon 18/01/2021 Tue 19/01/2021 Wed 20/01/2021 Thu 21/01/2021 Fri 22/01/2021 Sat 23/01/2021 Sun 24/01/2021 Mon 25/01/2021 Tue 26/01/2021 Wed 27/01/2021 Thu 28/01/2021 Fri 29/01/2021 Sat 30/01/2021 Sun 31/01/2021February 2021 Mon 01/02/2021 Tue 02/02/2021 Wed 03/02/2021 Thu 04/02/2021 Fri 05/02/2021 Sat 06/02/2021 Sun 07/02/2021 Mon 08/02/2021 Tue 09/02/2021 Wed 10/02/2021 Thu 11/02/2021 Fri 12/02/2021 Sat 13/02/2021 Sun 14/02/2021 Mon 15/02/2021 Tue 16/02/2021 Wed 17/02/2021 Thu 18/02/2021 Fri 19/02/2021 Sat 20/02/2021 Sun 21/02/2021 Mon 22/02/2021 Tue 23/02/2021 Wed 24/02/2021 Thu 25/02/2021 Fri 26/02/2021 Sat 27/02/2021 Sun 28/02/2021March 2021 Mon 01/03/2021 Tue 02/03/2021 Wed 03/03/2021 Thu 04/03/2021 Fri 05/03/2021 Sat 06/03/2021 Sun 07/03/2021 Mon 08/03/2021 Tue 09/03/2021 Wed 10/03/2021 Thu 11/03/2021 Fri 12/03/2021 Sat 13/03/2021 Sun 14/03/2021 Mon 15/03/2021 Tue 16/03/2021 Wed 17/03/2021 Thu 18/03/2021 Fri 19/03/2021 Sat 20/03/2021 Sun 21/03/2021 Mon 22/03/2021 Tue 23/03/2021 Wed 24/03/2021 Thu 25/03/2021 Fri 26/03/2021 Sat 27/03/2021 Sun 28/03/2021 Mon 29/03/2021 Tue 30/03/2021 Wed 31/03/2021April 2021 Thu 01/04/2021 Fri 02/04/2021 Sat 03/04/2021 Sun 04/04/2021 Mon 05/04/2021 Tue 06/04/2021 Wed 07/04/2021 Thu 08/04/2021 Fri 09/04/2021 Sat 10/04/2021 Sun 11/04/2021 Mon 12/04/2021 Tue 13/04/2021 Wed 14/04/2021 Thu 15/04/2021 Fri 16/04/2021 Sat 17/04/2021 Sun 18/04/2021 Mon 19/04/2021 Tue 20/04/2021 Wed 21/04/2021 Thu 22/04/2021 Fri 23/04/2021 Sat 24/04/2021 Sun 25/04/2021 Mon 26/04/2021 Tue 27/04/2021 Wed 28/04/2021 Thu 29/04/2021 Fri 30/04/2021May 2021 Sat 01/05/2021 Sun 02/05/2021 Mon 03/05/2021 Tue 04/05/2021 Wed 05/05/2021 Thu 06/05/2021 Fri 07/05/2021 Sat 08/05/2021 Sun 09/05/2021 Mon 10/05/2021 Tue 11/05/2021 Wed 12/05/2021 Thu 13/05/2021 Fri 14/05/2021 Sat 15/05/2021 Sun 16/05/2021 Mon 17/05/2021 Tue 18/05/2021 Wed 19/05/2021 Thu 20/05/2021 Fri 21/05/2021 Sat 22/05/2021 Sun 23/05/2021 Mon 24/05/2021 Tue 25/05/2021 Wed 26/05/2021 Thu 27/05/2021 Fri 28/05/2021 Sat 29/05/2021 Sun 30/05/2021 Mon 31/05/2021June 2021 Tue 01/06/2021 Wed 02/06/2021 Thu 03/06/2021 Fri 04/06/2021 Sat 05/06/2021 Sun 06/06/2021 Mon 07/06/2021 Tue 08/06/2021 Wed 09/06/2021 Thu 10/06/2021 Fri 11/06/2021 Sat 12/06/2021 Sun 13/06/2021 Mon 14/06/2021 Tue 15/06/2021 Wed 16/06/2021 Thu 17/06/2021 Fri 18/06/2021 Sat 19/06/2021 Sun 20/06/2021 Mon 21/06/2021 Tue 22/06/2021 Wed 23/06/2021 Thu 24/06/2021 Fri 25/06/2021 Sat 26/06/2021 Sun 27/06/2021 Mon 28/06/2021 Tue 29/06/2021 Wed 30/06/2021July 2021 Thu 01/07/2021 Fri 02/07/2021 Sat 03/07/2021 Sun 04/07/2021 Mon 05/07/2021 Tue 06/07/2021 Wed 07/07/2021 Thu 08/07/2021 Fri 09/07/2021 Sat 10/07/2021 Sun 11/07/2021 Mon 12/07/2021 Tue 13/07/2021 Wed 14/07/2021 Thu 15/07/2021 Fri 16/07/2021 Sat 17/07/2021 Sun 18/07/2021 Mon 19/07/2021 Tue 20/07/2021 Wed 21/07/2021 Thu 22/07/2021 Fri 23/07/2021 Sat 24/07/2021 Sun 25/07/2021 Mon 26/07/2021 Tue 27/07/2021 Wed 28/07/2021 Thu 29/07/2021 Fri 30/07/2021 Sat 31/07/2021August 2021 Sun 01/08/2021 Mon 02/08/2021 Tue 03/08/2021 Wed 04/08/2021 Thu 05/08/2021 Fri 06/08/2021 Sat 07/08/2021 Sun 08/08/2021 Mon 09/08/2021 Tue 10/08/2021 Wed 11/08/2021 Thu 12/08/2021 Fri 13/08/2021 Sat 14/08/2021 Sun 15/08/2021 Mon 16/08/2021 Tue 17/08/2021 Wed 18/08/2021 Thu 19/08/2021 Fri 20/08/2021 Sat 21/08/2021 Sun 22/08/2021 Mon 23/08/2021 Tue 24/08/2021 Wed 25/08/2021 Thu 26/08/2021 Fri 27/08/2021 Sat 28/08/2021 Sun 29/08/2021 Mon 30/08/2021 Tue 31/08/2021September 2021 Wed 01/09/2021 Thu 02/09/2021 Fri 03/09/2021 Sat 04/09/2021 Sun 05/09/2021 Mon 06/09/2021 Tue 07/09/2021 Wed 08/09/2021 Thu 09/09/2021 Fri 10/09/2021 Sat 11/09/2021 Sun 12/09/2021 Mon 13/09/2021 Tue 14/09/2021 Wed 15/09/2021 Thu 16/09/2021 Fri 17/09/2021 Sat 18/09/2021 Sun 19/09/2021 Mon 20/09/2021 Tue 21/09/2021 Wed 22/09/2021 Thu 23/09/2021 Fri 24/09/2021 Sat 25/09/2021 Sun 26/09/2021 Mon 27/09/2021 Tue 28/09/2021 Wed 29/09/2021 Thu 30/09/2021October 2021 Fri 01/10/2021 Sat 02/10/2021 Sun 03/10/2021 Mon 04/10/2021 Tue 05/10/2021 Wed 06/10/2021 Thu 07/10/2021 Fri 08/10/2021 Sat 09/10/2021 Sun 10/10/2021 Mon 11/10/2021 Tue 12/10/2021 Wed 13/10/2021 Thu 14/10/2021 Fri 15/10/2021 Sat 16/10/2021 Sun 17/10/2021 Mon 18/10/2021 Tue 19/10/2021 Wed 20/10/2021 Thu 21/10/2021 Fri 22/10/2021 Sat 23/10/2021 Sun 24/10/2021 Mon 25/10/2021 Tue 26/10/2021 Wed 27/10/2021 Thu 28/10/2021 Fri 29/10/2021 Sat 30/10/2021 Sun 31/10/2021November 2021 Mon 01/11/2021 Tue 02/11/2021 Wed 03/11/2021 Thu 04/11/2021 Fri 05/11/2021 Sat 06/11/2021 Sun 07/11/2021 Mon 08/11/2021 Tue 09/11/2021 Wed 10/11/2021 Thu 11/11/2021 Fri 12/11/2021 Sat 13/11/2021 Sun 14/11/2021 Mon 15/11/2021 Tue 16/11/2021 Wed 17/11/2021 Thu 18/11/2021 Fri 19/11/2021 Sat 20/11/2021 Sun 21/11/2021 Mon 22/11/2021 Tue 23/11/2021 Wed 24/11/2021 Thu 25/11/2021 Fri 26/11/2021 Sat 27/11/2021 Sun 28/11/2021 Mon 29/11/2021 Tue 30/11/2021December 2021 Wed 01/12/2021 Thu 02/12/2021 Fri 03/12/2021 Sat 04/12/2021 Sun 05/12/2021 Mon 06/12/2021 Tue 07/12/2021 Wed 08/12/2021 Thu 09/12/2021 Fri 10/12/2021 Sat 11/12/2021 Sun 12/12/2021 Mon 13/12/2021 Tue 14/12/2021 Wed 15/12/2021 Thu 16/12/2021 Fri 17/12/2021 Sat 18/12/2021 Sun 19/12/2021 Mon 20/12/2021 Tue 21/12/2021 Wed 22/12/2021 Thu 23/12/2021 Fri 24/12/2021 Sat 25/12/2021 Sun 26/12/2021 Mon 27/12/2021 Tue 28/12/2021 Wed 29/12/2021 Thu 30/12/2021 Fri 31/12/2021January 2022 Sat 01/01/2022 Sun 02/01/2022 Mon 03/01/2022 Tue 04/01/2022 Wed 05/01/2022 Thu 06/01/2022 Fri 07/01/2022 Sat 08/01/2022 Sun 09/01/2022 Mon 10/01/2022 Tue 11/01/2022 Wed 12/01/2022 Thu 13/01/2022 Fri 14/01/2022 Sat 15/01/2022 Sun 16/01/2022 Mon 17/01/2022 Tue 18/01/2022 Wed 19/01/2022 Thu 20/01/2022 Fri 21/01/2022 Sat 22/01/2022 Sun 23/01/2022 Mon 24/01/2022 Tue 25/01/2022 Wed 26/01/2022 Thu 27/01/2022 Fri 28/01/2022 Sat 29/01/2022 Sun 30/01/2022 Mon 31/01/2022February 2022 Tue 01/02/2022 Wed 02/02/2022 Thu 03/02/2022 Fri 04/02/2022 Sat 05/02/2022 Sun 06/02/2022 Mon 07/02/2022 Tue 08/02/2022 Wed 09/02/2022 Thu 10/02/2022 Fri 11/02/2022 Sat 12/02/2022 Sun 13/02/2022 Mon 14/02/2022 Tue 15/02/2022 Wed 16/02/2022 Thu 17/02/2022 Fri 18/02/2022 Sat 19/02/2022 Sun 20/02/2022 Mon 21/02/2022
Number of nights *
Number of adults *
I agree to my contact details being stored and used to receive communications from Suites and Villas. Click here to view our Privacy Policy
For the love of travel
If you love inspiring travel ideas as much as we love curating them; then subscribe to our regular newsletters to be kept up-to-date on new additions to our collection and ideas for your next adventure.
Get inspired and stay up to date with the world of travel and get early access to great travel offers by subscribing to Your World, our free newsletter
I agree to my contact details being stored and used to receive communications from Suites and Villas by letsgo2. Click here to view our Privacy Policy
Exceptional holidays reimagined
hello@reglarcollection.com
7 Bell Yard, London, WC2A 2JR
© 2020 The Ickenham Travel Group All rights reserved. The air holidays and flights shown are ATOL protected by the Civil Aviation Authority. Our ATOL number is ATOL 4950. Protection extends primarily to customers who book and pay in the United Kingdom. Click on the ATOL logo for verification. Reglar Collection is a division of Ickenham Travel Group PLC. Registered in England: 7 Bell Yard, London. WC2A 2JR. No. 986305. VAT Reg No: 222910006.


text:
How safe is your data?
Published On: March 20, 2020 09:18 AM NPT By: URZA ACHARYA
Sandipa Tamang, interior designer based in Lalitpur, has been trying to limit her internet use as much as possible. Apparently, there was an incident that has made her a bit skeptical about privacy issues online. "I was talking to my friend about something and when I opened the internet later, a webpage showed me suggestions regarding that thing which left me a bit a paranoid," she says. She says though this could be a coincidence, it has her thinking twice before entering any personal data on the world wide web.
"I try to keep my data entry as basic as possible."
Turns out, this type of skepticism is quite common. In fact, all the people The Week spoke to admitted that they do whatever is in their power to secure their data from being misused or taken without permission. Moreover, recent scandals like the Cambridge Analytica Scandal, the Virgin Media data breach have created fear amongst netizens who aren't sure about where their data is going and how it's being used.
In 2018, Facebook revealed that 30 million accounts were affected in a data breach. The company said hackers were able to access personal information for nearly half of those accounts.
Hrishav Tandukar, assistant lecturer in Islington College who is also doing his master's in data analysis, says that the issue of data breaching is real and significant, especially in the current times.
"Oftentimes, hackers can steal your data by tricking you into entering your information," he says explaining that people often play with the domain name to trick you into thinking you're logging into a genuine website.
For example, you might think you're logging into your Facebook using "facebook.com" but in actuality, you're entering your email and password in a fake website created by hackers that looks almost identical to the real website with a very similar domain name like "facebooks.com". Tandukar says that after you enter your data the page seems to refresh which means another party now has your private data.
Sagharsha Bhattarai, software engineer, also agrees that the internet can be a very tricky place to navigate, especially when it comes to data privacy. For him, data privacy means giving out as little data as possible to online websites and portals. "Many times, if we download a gaming app they ask for access to our contact or gallery which is redundant for an app you downloaded to play games. So, instead of saying yes to everything without properly reading anything, we can choose to skip or say no," he says.
Similarly, many apps try to sync with your other accounts in the pretext of making things easier for you which can also lead you to give out information about your location, photographs, etc in an indirect way.
Bhattarai keeps the basic data needed for a login to a minimum without giving out too many details. "You don't have to enter everything they ask for. In case of the internet, it's best to do the bare minimum," he adds.
Similarly, Bhattarai says that many of us don't have the habit of reading privacy policies or terms and conditions of websites and apps on the internet and so we might unknowingly be allowing them to take our information.
"Instead of saying yes to each and everything in order to get over the boring parts of software installation, I take my time to understand the rules and policies," he says adding that he's also wary of these unrecognized, free tool providing apps or websites which might not be held liable if your data does get stolen. "It's always important to check your source and how liable it is if anything were to go wrong."
Apekshya Subedi, law student, agrees with Bhattarai's argument that we tend to be pretty hasty when it comes to properly reading privacy policies of a website before giving them our information. "In the past, I personally wouldn't think twice before saying yes without reading the terms and conditions to get on with the app, but recent news about data breaching scandals have conditioned me to be a little more careful," she says.
Subedi says that since getting through the entire policy can be tedious, one can skim through it focusing on the privacy part of the text.
Though those The Week spoke to had valid reasons for fearing data breaching, all admitted that, in this day and age, it would be almost impossible to live without the internet. "But it's imperative that we learn to protect ourselves and keep our private information from reaching the wrong hands," says Subedi.
Agreeing with Subedi, Tandukar says that the best solution for this is awareness. "Whether or not your information will go to the wrong people entirely depends on how you navigate the internet," he says. Tandukar recently worked on a report on data privacy and he found that most people in Nepal aren't aware of just how important one's data is and also how necessary it is to protect it.
"Elections, political inclinations and the entire state of a nation can be overturned by the information one gets from stealing data. As private data gives acts as a window to an individual's location, age, likes and dislikes, it will be very easy to influence that person's thought process by manipulating what s/he sees when s/he goes on the internet," he says.
The first thing Tandukar recommends is for anyone who uses the internet and online apps to go to the "settings" menu and modify the privacy settings. "You can manually restrict the amount of data that the app or website is taking from you," he says.
Moreover, he also advises people to check if the website/app they're using comes from a verified source or not. "Always check the URL of the page you're visiting and if something seems off, it's better to get off that page entirely," he adds.
Hackers or data breachers can't take your information unless you hand it to them either directly or indirectly. And so by being aware of matters like data breaching, data fishing, and other forms of cybercrimes, one can protect their private information.
Tandukar also believes that offices and organizations should conduct workshops or meeting that teaches their employees or people in general about data privacy issues and how to navigate through it. "Especially in a professional environment when we do a lot of confidential work over the internet, it's important to be aware of how our digital footprint can be easily traced and act accordingly," he concludes.
acharyaurza8170@gmail.com
online_privacy_issues
personal_data
world_wide_web
Cambridge_Analytica_Scandal
Virgin_Media_data_breach
Weather Channel app accused of selling users' personal data
LOS ANGELES, Jan 5: People relied on the most popular mobile weather app to track forecasts that determined whether they chose...

redpajama_set_name: RedPajamaCommonCrawl


Along with my previous article on expository preaching, allow me to approach this short article anecdotally. Earnest prayer has long been dear to me because I found it to be so lacking during my teenage years in my broader PC(USA) context. Now, my home congregation was rather more conservative. However, we were active within the wider networks of the PC(USA) and therefore my description is intended to tell of the general milieu of the mainline denomination as I experienced it, as a foil to what I found in the PCA.
One of the things I first noticed about the prayers in many of these services was how utterly bored the speakers sounded. They seemed listless and stale and as if the speakers had no sort of emotional investment whatsoever in the words they were speaking! Now, I realize that a lot of this is subjective evaluation; simply because a man is animated is no indicator of the sincerity or piety behind his prayer. But nevertheless, many times those who were leading in prayer prayed with a painfully dry, tedious monotone that left one in doubt as to whether they believed the words they were saying at all.
In my adolescent estimation, the prayer life of these congregations and networks was devoid of any life, and, having few models of prayer to imitate, it was to the detriment of my own piety.
Fast forward to my college years in a rural PCA congregation. I heard prayers that were warm, sincere-sounding, and lively. I heard us pray for the conversion of the lost, adoring God for his being and perfections and for his goodness and grace to sinners; for the cause of world missions and evangelism; for families struggling with infertility; for sicknesses; for those in mourning; for families who had suffered gross injustices and pains; prayers for God's guidance and wisdom to be given to our governing officials; prayers for our own souls' growth in godliness and reception to the Word of God, etc. Here–at last!–I found meaty, biblical prayers that I could sink my teeth into.
One of the elders in my church introduced me to the concept of studied prayers. As he explained, while there was nothing wrong with "extemporaneous" prayer, it is helpful in leading the congregation to have given some thought and preparation to the prayer beforehand. While it was not required to write out a full "prayer manuscript" per se, he would often think of items to highlight: issues, theological ideas, etc. and outline them on paper to remind himself, as well as allowing for "wiggle room" to add prayer concerns based on the congregation's need for the day or season.
Moreover, I was introduced to an entirely new concept: prayer meetings. Usually taking place on Wednesday nights, a good portion of the congregation would gather for the specific purpose of spending an hour or so in prayer together for various items in the life of the congregation and the kingdom of God more broadly. "What a wonderful concept!" I thought. I was there every week. Hearing the prayers of the elders and other seasoned saints was so incredibly encouraging and it was such a helpful model to me in learning how to structure my own prayers.
I heard prayers that were short and simple, and prayers that were longer and more eloquent, but every time, I heard prayers that were earnest, sincere, and biblical. Whether it was confessing sin, or longing for the conversion of the lost, or praying for growth in grace, or for health concerns, I heard prayers that were serious and hopeful and reverent. And my soul was edified and greatly encouraged.
Our Lord Jesus himself models for us what the priorities for prayer should be, doesn't he? In Matthew 6:9-13, he demonstrates for us the great contours and content of our prayers ought to include adoration of our God in light of his holy perfections, praying for the advance of his kingdom (the reign of Christ in the souls of men, among other aspects) and accomplishment of his will, confessing our sins, asking his help for the living of the Christian life, and acknowledging our dependence on him even as we seek his aid in supplying our daily needs.
Moreover, the Psalmist describes a raw, unfiltered, and earnest experience of prayer as he cries to his God, as his soul pants for God, thirsts for the living God, and as he pours out his soul to this God (Psalm 42:1-4).
Friends, this is what the precious souls in our churches need and this is the biblical model: prayers that are sensitive and sincere, warm and winsome, passionate and pastoral. Let us not lose sight of how paradoxically simple and yet how profound and vibrant earnest prayer can be in the care of souls, in our witness to the world, and to the honor of King Jesus.


text:
Q: I have a problem using pydub library in python, Even I have read its documentation and I have downloaded it in my windows mahcine

I also have tried to run the project on my linux machine (distribution: Kali Linux) and I have imported the pydub, but it says module not found even after I have downloaded it

redpajama_set_name: RedPajamaStackExchange


Pawtimore is "leader of the pack" in the local dog-grooming industry, and now Baltimore's finest pet salon and boutique is turning 1! Located in the heart of Historic Federal Hill, this "groomery" offers multiple packages specifically designed to cater to all four-legged friends who venture through their doors. Also showcasing an impressive selection of quality pet accessories and apparel, Pawtimore offers a complete line of cleaning and hygiene products for man's best friend, and a remarkable variety of gourmet treats stylistically made right on location.
So come on down on Saturday, May 9th from 10am-3pm and have a few wags with us! Throw your name in the drawing for a door prize and enjoy a complimentary sangria or microbrew. Take as many treats as you'd like, because there's sure to be plenty! Loki's Lifestyle and Pub Dog Drafthouse will be joining us on-site, each featuring unique promotions for this special event. We're looking forward to shaking your paw, and can't wait to see you there!


text:
Chasing the American Dream
As the story begins, David Svehla is a US Army Captain during WW2. His unit discovers the Dora concentration camp, where Jewish POWs created tunnels to camouflage Germany's secret V-2 rocket facility. A few ill POWs remain at the camp, but all else is deserted.
One Stormy Night
Lachlan Hart, founder of MindThrive AI (artificial intelligence), creates an algorithm with his best friend, Matteo, that takes off and makes them wealthy. Matteo is injured in a skiing accident, and Lachlan runs their dream company alone. He drives himself to succeed, by working efficiently and by cutting himself off emotionally from others.
The Guest is a Goner (Sedona Spirit Book 1)
COZY PARANORMAL MYSTERY: When Bernadette Maxwell returns home from an eventful, accident-filled vacation, she finds more than she bargained for. Bernadette, or Bernie as her friends and family call her, owns and manages an Inn she established in the house her grandmother Ruby left her.
Resisting Dylan (Cowboy Inspired #2)
Dylan Dawson, an up and coming rodeo star, thinks he's still in love and wants to reconnect with his longtime girlfriend, Shelby. Shelby has moved to New York and is living the city life. When Dylan comes to reconnect with her, Shelby, who is already dating a new beau, persuades her roommate Kate to take Dylan to see the city's sites.
Chocolate Raspberry Magic
Trinity, the assistant manager for Salem's Wildlife Sanctuary, is quiet, friendly, and hardworking… but she has had awful luck with men. She has a crazy strong attraction to the new employee at the sanctuary, Paul, but she knows he is struggling with demons from his past as a Special Forces veteran, making a successful relationship with him seem almost impossible.


Advise and assist all international students on university policies, immigration regulations, personal and financial matters and render assistance toward support programs on campus and locally in Stillwater.
Process and prepare all types of forms and reports required by the USCIS (United States Citizenship Immigration Services), U.S. Department of State and any other federal or educational institution.
Issue employment clearances and assist with annual tax form preparations.
Facilitate cultural connections by coordinating with departmental organizations, community organizations and international organizations that focus on international students at OSU and Stillwater.
Maintain a listserv and website with pertinent information for international students.
Update international students with changes to procedures and policies at OSU and in the United States.
Conduct research, complete surveys and statistical reports.
Be on call for emergencies involving the police and hospital.
ISS assists all international sponsored students, scholars and international faculty with matters pertaining to the government, private agencies and international-sponsored student alumni.
The Office of International Students and Scholars invites international students and scholars as well as American students, faculty, staff and community members to access its services.


text:
Does Free Music Service Spotify Offer Hope For The Future?
Luke Turner , January 21st, 2009 14:44
Is record label-backed music streaming service Spotify the best response yet to the issue of illegal filesharing?
For a few years now the music industry has been desperately scrambling for a business and distribution model that would go some way in persuading the panting stallion of illegal downloading/file sharing/torrenting to, if not get back behind the stable door, then at least to agree to stay in the nearby paddock. Thus far, there's been little success, and the recent news that 95% of all online file transfers were illegal surely caused no small distress in the already vexed headquarters of the major labels.
Could new service Spotify, currently in an invite-only, beta phase, be the answer to their prayers? Spotify works not via file sharing or downloads, but by providing reasonable quality (around 160kb/s) streams of music via a simple to use interface not dissimilar to iTunes. You can listen to streams for free, with the occasional advert (about once every album, at my reckoning) funding a pool of revenue that then goes to recompense the labels and artists. Further revenue is generated via a membership scheme whereby, for a daily or monthly fee (99p and £9.99 respectively), the user avoids the advertisements and gains invite privileges.
I signed up last week, and since then have had a rare old time ploughing through bits of old back catalogue that I've missed, following recommended artist links, rediscovering records I've not listened to in years, or treating it as a try-before-you-by service – something that the struggling independent record shop sector would do well to work on embracing.
Spotify might lack the social networking aspect of last.fm, but this to me is a strength, rather than a weakness – especially for us users who doesn't care two hoots about being more of an Animal Collective obsessive than username P4KsBumChum. The sort of refined gentleman who reads the Quietus eschews such showing off, content to gather his closest confidants together to discuss the works of Mayhem in his club over a port.
Yes, there are the occasional technical glitches and gaps in the catalogue, especially in the less-travelled parts of the musical landscape. This will no doubt be addressed as the service develops. You might complain about the adverts, but the monthly sign-up fee answers that. And anyway, there's something weirdly satisfying about Moira Stewart telling you to pay your tax halfway through an afternoon of Front 242.
Spotify works not merely because it is a carrot, rather than a stick. For the first time, record labels have understood that MP3s are ephemeral, unquantifiable things entirely divorced from the idea of the artefact that so many of us still cherish. You can feel no pride of ownership over an MP3, they merely take time to download and clutter up computer hard drives. Why download an MP3, legally or otherwise, when Spotify provides such a simple way of accessing and listening to it? You might argue that you can't take Spotify with you on the daily commute, but there's always fast-developing mobile phone technology to plug that gap.
It's clear that the current rate of illegal file-sharing cannot be sustained. I'd like to think that most music fans see the need to contribute towards the music-making process if they're to continue to see artists receive at least some recompense for their labours. Early indications are that Spotify might well be the what record labels, musicians and, most importantly, music fans have been waiting for, for so long. The hope is now that the take-up is not so fast as to impair functionality, and that some of those artists who've thus far said they won't allow their tracks to be featured realise that their ostrich approach is no longer viable, and get involved. Yes Metallica, yet again, we're talking to you.
A Hard Habit To Break: The Quietus' Lent Themed Spotify Playlist »
Spotify Helping Industry Fight Illegal Downloads? »
The Sonic Cathedral Spotify-Themed Playlist Of Shoey Goodness »
Spotify Reveal Google Android Mobile Service »
Music Streaming Going From Strength To Strength »
MORE FROM LUKE TURNER
Oooff, Ken! It's John Shuttleworth's Baker's Dozen! »
LISTEN: Brian Eno's Election Song! »
LIVE REPORT: Fat White Family »
Supergroup Formed For tQ Xmas Fundraiser! »
A Roaming Suburban Boy: William Doyle Interviewed »


The main body of our farm sits on a bend in the South Toe River. We are definitely not the first ones to coax a living from the sandy loam. We are always reminded of those who came before as we pick points and pottery from our soils, some thousands of years old. We grow six acres of Biodynamic vegetables in a scattering of soil types and fields, from sandy loam to clay loam. As a wife and husband team of Nicole DelCogliano and Gaelan Corozine we have been here since 2001, along with our two daughters.
Our farming philosophy: We started practicing biodynamic farming on the land in 2004. We feel it speaks to our philosophy and perspective of approaching our farm as a whole organism. Husbanding animals is also very important for us as we make our own Biodynamic compost from their manures .Farming is more than economics to us; it is a lifestyle and a culture that we strive for. Our two daughters have grown up from birth on our backs in the fields and we are immensely proud of that.
What we grow and how: We grow vegetables of all kinds, a mix of heirlooms and hybrids, outdoors and in 3 high tunnels. We have worked hard to find which varieties work well for our land, but are always exploring new products. We use a 45 hp Kioti Tractor for bed preparation, primarily using a Imants spader. As inquisitive people we nurture an understanding and study of the land we farm on. All of our cultivation is done by hand with scuffle hoes or hand weeding. Over time we have seen our weed load lessen along with disease pressure and now we have cut back severely on supplemental watering. Believing that good veggies taste better when they have to work a little to get what they need.
We market 9- 11 months a year, selling at the oldest market in Asheville, North Asheville Tailgate Market and Asheville City Market. We also sell to regional restaurants, such as Farm Burger (Asheville, NC), Early Girl Eatery (Asheville, NC), Smoky Park Supper Club (Asheville, NC), Cucina 24 (Asheville, NC), Nightbell (Asheville, NC), Rhubarb (Asheville, NC), and Curate.
We also have dried flower wreaths for sale.
"We have been working with Green Toe for almost 15 years and have been pleased 100% of the time - both with product and service."
"I have been a member of Green Toe Ground's CSA for over 12 years. Having the CSA with them is a way of life for me and my family. Gaelan and Nicole have become close friends of mine. They have a wonderful way of connecting with customers through the food they sell. I believe they embody what it means to be an organic farmer in their relationship with the land, their lifestyle and beliefs, and the people they serve."
We have been farming for twenty years and we still love it. During that time we have worked side by side with over twenty young folks most of whom have gone on to form a relationship with farming in some manner. As certified farm nerds we love to share our experiences and anecdotes but love to hear yours as well. We want folks who are engaged and interested in pursuing agriculture in some manner. Being farmers does not define who we are as we have travelled extensively and are active in social justice work. You will take part in ALL aspects of farm work, from harvest management to animal husbandry, to greenhouse work and long hours weeding and harvesting. You will also have the opportunity to learn marketing, sales and some aspects of agritourism. Above all we would hope that you make our farm YOUR farm for however long you stay.
We offer apprenticeships mid March thru October, with the possibility to extend. We work Monday through Friday 7AM to 5 or 6PM as needed, with a 2 hours lunch break. As the weather gets warmer, we often start earlier in the morning. Tuesdays and Fridays are harvest days, and Wednesdays are delivery days to restaurants in Asheville. The Asheville City Market and North Asheville tailgate markets require us to leave the farm by 5:15AM on Saturdays. Apprentices come to market on a rotational basis, and when not at market, cover other chores such as feeding and watering of animals, watering starts in the greenhouse, etc.
We offer a weekly cash stipend and monthly food stipend to use at our local food cooperative or the farmers market. Apprentices live in an off the grid cabin with water catchment system for washing dishes. There is an oven and stove, outdoor toilet, and a solar shower bag at the cabin. Apprentices do have access to a refrigerator. We offer vegetables from the farm, eggs, and milk as available. Apprentices get a full paid week off each season, organized in advance. We also make room for days off as needed for friend and family visits. We also pay for apprentices to attend the Southeast Regional Biodynamic Gathering each October in TN as well as membership in CRAFT, an apprentice and farmer network. We do not offer Wifi but locally the Celo Community Center (right down the road) also has wifi access and it is open to the public to use. We request limited to no cell phone use during farm working hours. Interning with us will give you a breadth of knowledge about how to grow and market veggies. Farming is hard and takes commitment, but the rewards are great if you put in the time. We recognize that we are asking a lot as farmers but feel that we have a lot to offer, not just basic farm work, but a deeper connection to land and environment.
Our farm is an active member in the CRAFT network.
We live in a beautiful place in the South Toe River Valley at the base of the Black Mountains, in the township of Celo, NC. Once summer starts, there are lots of music festivals and events in Burnsville and the surrounding regions. We have a large party for the 4th of July, with music and a DJ, Farm Olympics, and fireworks. Celo has a pickup soccer game every Sunday. Biking and walking and hiking trails are abundant in Celo and in Pisgah National Forest, and we have the best swimming holes in the area right on our property!
We request applicants come with an open and curious mind and a willingness to adapt and learn. These are critical skills to success at our farm. We may not do everything perfectly or the way you expect, but we do have our reasons.
A car or truck is handy to have at our farm so you can leave when you'd like.
To inquire about employment opportunities, please contact us by email or phone in December or January or visit our website for further information.
"Working with Gaelen and Nicole was a really special experience. They are simultaneously filled with knowledge and also understand the value of self experimentation as a powerful way of learning. They have their ways and practices, but I was able to try things out in my way, and encouraged to use my own skills and understanding to perform a task. There is structure, and also freedom. The farm itself is idyllic, dropped in the heart of the Blue Ridge mountains, nestled up against the stunning South Toe river. You work hard and play hard. There is time for exploration of the area and dips into the cool water when a days a hard work is said and done. The farm is a run using biodynamic principals which is powerful way to orient oneself around growing systems and food production."
"Nicole and Gaelan are great farmers to work for and learn from! Lifestyle is rustic, a bit remote, and absolutely lovely. Workload is fair, and varies depending on the time of the season. Overall highly recommend Green Toe Ground if you are looking for experience with a small scale, minimally-mechanized operation... especially if you're interested in learning about biodynamics, animals, living off grid, and getting to know some truly great people!"
"Wonderful farm in gorgeous setting. Salt of the earth folks. The most realistic farming experience."
We host 1-2 farm dinners per season.
Our farm is available for event space (limited). Please visit our website for more information.


Click any of the links below to see the savings available to you - just for being an Advancial member!
Click here to see all rewards and discounts available to you for being a credit union member.
Shop your favorite online stores and earn cash back with Love to Shop.
*To find Advancial, select "Texas" in the search field.
Keep more of your hard earned money this tax season!
Enjoy discounted tickets to Six Flags Over Texas, located in Arlington, TX!
Enjoy discounted tickets to Six Flags Fiesta in San Antonio, TX!


text:
"""Utility module for translating XML API objects to/from JSON objects."""

from __future__ import absolute_import
from __future__ import print_function
from __future__ import division
from __future__ import unicode_literals

import datetime
import json
import re
import textwrap
import xml.etree.ElementTree
from xml.etree.ElementTree import ParseError as XmlParseError

import six
from apitools.base.protorpclite.util import decode_datetime
from apitools.base.py import encoding
import boto
from boto.gs.acl import ACL
from boto.gs.acl import ALL_AUTHENTICATED_USERS
from boto.gs.acl import ALL_USERS
from boto.gs.acl import Entries
from boto.gs.acl import Entry
from boto.gs.acl import GROUP_BY_DOMAIN
from boto.gs.acl import GROUP_BY_EMAIL
from boto.gs.acl import GROUP_BY_ID
from boto.gs.acl import USER_BY_EMAIL
from boto.gs.acl import USER_BY_ID
from boto.s3.tagging import Tags
from boto.s3.tagging import TagSet

from gslib.cloud_api import ArgumentException
from gslib.cloud_api import BucketNotFoundException
from gslib.cloud_api import NotFoundException
from gslib.cloud_api import Preconditions
from gslib.exception import CommandException
from gslib.third_party.storage_apitools import storage_v1_messages as apitools_messages
from gslib.utils.constants import S3_ACL_MARKER_GUID
from gslib.utils.constants import S3_MARKER_GUIDS

if six.PY3:
  long = int

CACHE_CONTROL_REGEX = re.compile(r'^cache-control', re.I)
CONTENT_DISPOSITION_REGEX = re.compile(r'^content-disposition', re.I)
CONTENT_ENCODING_REGEX = re.compile(r'^content-encoding', re.I)
CONTENT_LANGUAGE_REGEX = re.compile(r'^content-language', re.I)
CONTENT_MD5_REGEX = re.compile(r'^content-md5', re.I)
CONTENT_TYPE_REGEX = re.compile(r'^content-type', re.I)
CUSTOM_TIME_REGEX = re.compile(r'^custom-time', re.I)
GOOG_API_VERSION_REGEX = re.compile(r'^x-goog-api-version', re.I)
GOOG_GENERATION_MATCH_REGEX = re.compile(r'^x-goog-if-generation-match', re.I)
GOOG_METAGENERATION_MATCH_REGEX = re.compile(r'^x-goog-if-metageneration-match',
                                             re.I)
CUSTOM_GOOG_METADATA_REGEX = re.compile(r'^x-goog-meta-(?P<header_key>.*)',
                                        re.I)
CUSTOM_AMZ_METADATA_REGEX = re.compile(r'^x-amz-meta-(?P<header_key>.*)', re.I)
CUSTOM_AMZ_HEADER_REGEX = re.compile(r'^x-amz-(?P<header_key>.*)', re.I)

# This distinguishes S3 custom headers from S3 metadata on objects.
S3_HEADER_PREFIX = 'custom-amz-header'

DEFAULT_CONTENT_TYPE = 'application/octet-stream'

# Because CORS is just a list in apitools, we need special handling or blank
# CORS lists will get sent with other configuration commands such as lifecycle,
# which would cause CORS configuration to be unintentionally removed.
# Protorpc defaults list values to an empty list, and won't allow us to set the
# value to None like other configuration fields, so there is no way to
# distinguish the default value from when we actually want to remove the CORS
# configuration.  To work around this, we create a dummy CORS entry that
# signifies that we should nullify the CORS configuration.
# A value of [] means don't modify the CORS configuration.
# A value of REMOVE_CORS_CONFIG means remove the CORS configuration.
REMOVE_CORS_CONFIG = [
    apitools_messages.Bucket.CorsValueListEntry(maxAgeSeconds=-1,
                                                method=['REMOVE_CORS_CONFIG'])
]

# Similar to CORS above, we need a sentinel value allowing us to specify
# when a default object ACL should be private (containing no entries).
# A defaultObjectAcl value of [] means don't modify the default object ACL.
# A value of [PRIVATE_DEFAULT_OBJ_ACL] means create an empty/private default
# object ACL.
PRIVATE_DEFAULT_OBJ_ACL = apitools_messages.ObjectAccessControl(
    id='PRIVATE_DEFAULT_OBJ_ACL')

def ObjectMetadataFromHeaders(headers):
  """Creates object metadata according to the provided headers.

  gsutil -h allows specifiying various headers (originally intended
  to be passed to boto in gsutil v3).  For the JSON API to be compatible with
  this option, we need to parse these headers into gsutil_api Object fields.

  Args:
    headers: Dict of headers passed via gsutil -h

  Raises:
    ArgumentException if an invalid header is encountered.

  Returns:
    apitools Object with relevant fields populated from headers.
  """
  obj_metadata = apitools_messages.Object()
  for header, value in headers.items():
    if CACHE_CONTROL_REGEX.match(header):
      obj_metadata.cacheControl = value.strip()
    elif CONTENT_DISPOSITION_REGEX.match(header):
      obj_metadata.contentDisposition = value.strip()
    elif CONTENT_ENCODING_REGEX.match(header):
      obj_metadata.contentEncoding = value.strip()
    elif CONTENT_MD5_REGEX.match(header):
      obj_metadata.md5Hash = value.strip()
    elif CONTENT_LANGUAGE_REGEX.match(header):
      obj_metadata.contentLanguage = value.strip()
    elif CONTENT_TYPE_REGEX.match(header):
      if not value:
        obj_metadata.contentType = DEFAULT_CONTENT_TYPE
      else:
        obj_metadata.contentType = value.strip()
    elif CUSTOM_TIME_REGEX.match(header):
      obj_metadata.customTime = decode_datetime(value.strip())
    elif GOOG_API_VERSION_REGEX.match(header):
      # API version is only relevant for XML, ignore and rely on the XML API
      # to add the appropriate version.
      continue
    elif GOOG_GENERATION_MATCH_REGEX.match(header):
      # Preconditions are handled elsewhere, but allow these headers through.
      continue
    elif GOOG_METAGENERATION_MATCH_REGEX.match(header):
      # Preconditions are handled elsewhere, but allow these headers through.
      continue
    else:
      custom_goog_metadata_match = CUSTOM_GOOG_METADATA_REGEX.match(header)
      custom_amz_metadata_match = CUSTOM_AMZ_METADATA_REGEX.match(header)
      custom_amz_header_match = CUSTOM_AMZ_HEADER_REGEX.match(header)
      header_key = None
      if custom_goog_metadata_match:
        header_key = custom_goog_metadata_match.group('header_key')
      elif custom_amz_metadata_match:
        header_key = custom_amz_metadata_match.group('header_key')
      elif custom_amz_header_match:
        # If we got here we are guaranteed by the prior statement that this is
        # not an x-amz-meta- header.
        header_key = (S3_HEADER_PREFIX +
                      custom_amz_header_match.group('header_key'))
      if header_key:
        if header_key.lower() == 'x-goog-content-language':
          # Work around content-language being inserted into custom metadata.
          continue
        if not obj_metadata.metadata:
          obj_metadata.metadata = apitools_messages.Object.MetadataValue()
        if not obj_metadata.metadata.additionalProperties:
          obj_metadata.metadata.additionalProperties = []
        obj_metadata.metadata.additionalProperties.append(
            apitools_messages.Object.MetadataValue.AdditionalProperty(
                key=header_key, value=value))
      else:
        raise ArgumentException('Invalid header specified: %s:%s' %
                                (header, value))
  return obj_metadata

def HeadersFromObjectMetadata(dst_obj_metadata, provider):
  """Creates a header dictionary based on existing object metadata.

  Args:
    dst_obj_metadata: Object metadata to create the headers from.
    provider: Provider string ('gs' or 's3').

  Returns:
    Headers dictionary.
  """
  headers = {}
  if not dst_obj_metadata:
    return
  # Metadata values of '' mean suppress/remove this header.
  if dst_obj_metadata.cacheControl is not None:
    if not dst_obj_metadata.cacheControl:
      headers['cache-control'] = None
    else:
      headers['cache-control'] = dst_obj_metadata.cacheControl.strip()
  if dst_obj_metadata.contentDisposition:
    if not dst_obj_metadata.contentDisposition:
      headers['content-disposition'] = None
    else:
      headers['content-disposition'] = (
          dst_obj_metadata.contentDisposition.strip())
  if dst_obj_metadata.contentEncoding:
    if not dst_obj_metadata.contentEncoding:
      headers['content-encoding'] = None
    else:
      headers['content-encoding'] = dst_obj_metadata.contentEncoding.strip()
  if dst_obj_metadata.contentLanguage:
    if not dst_obj_metadata.contentLanguage:
      headers['content-language'] = None
    else:
      headers['content-language'] = dst_obj_metadata.contentLanguage.strip()
  if dst_obj_metadata.md5Hash:
    if not dst_obj_metadata.md5Hash:
      headers['Content-MD5'] = None
    else:
      headers['Content-MD5'] = dst_obj_metadata.md5Hash.strip()
  if dst_obj_metadata.contentType is not None:
    if not dst_obj_metadata.contentType:
      headers['content-type'] = None
    else:
      headers['content-type'] = dst_obj_metadata.contentType.strip()
  if dst_obj_metadata.customTime is not None:
    if not dst_obj_metadata.customTime:
      headers['custom-time'] = None
    else:
      headers['custom-time'] = dst_obj_metadata.customTime.strip()
  if dst_obj_metadata.storageClass:
    header_name = 'storage-class'
    if provider == 'gs':
      header_name = 'x-goog-' + header_name
    elif provider == 's3':
      header_name = 'x-amz-' + header_name
    else:
      raise ArgumentException('Invalid provider specified: %s' % provider)
    headers[header_name] = dst_obj_metadata.storageClass.strip()
  if (dst_obj_metadata.metadata and
      dst_obj_metadata.metadata.additionalProperties):
    for additional_property in dst_obj_metadata.metadata.additionalProperties:
      # Work around content-language being inserted into custom metadata by
      # the XML API.
      if additional_property.key == 'content-language':
        continue
      # Don't translate special metadata markers.
      if additional_property.key in S3_MARKER_GUIDS:
        continue
      if provider == 'gs':
        header_name = 'x-goog-meta-' + additional_property.key
      elif provider == 's3':
        if additional_property.key.startswith(S3_HEADER_PREFIX):
          header_name = ('x-amz-' +
                         additional_property.key[len(S3_HEADER_PREFIX):])
        else:
          header_name = 'x-amz-meta-' + additional_property.key
      else:
        raise ArgumentException('Invalid provider specified: %s' % provider)
      if (additional_property.value is not None and
          not additional_property.value):
        headers[header_name] = None
      else:
        headers[header_name] = additional_property.value
  return headers

def CopyObjectMetadata(src_obj_metadata, dst_obj_metadata, override=False):
  """Copies metadata from src_obj_metadata to dst_obj_metadata.

  Args:
    src_obj_metadata: Metadata from source object.
    dst_obj_metadata: Initialized metadata for destination object.
    override: If true, will overwrite metadata in destination object.
              If false, only writes metadata for values that don't already
              exist.
  """
  if override or not dst_obj_metadata.cacheControl:
    dst_obj_metadata.cacheControl = src_obj_metadata.cacheControl
  if override or not dst_obj_metadata.contentDisposition:
    dst_obj_metadata.contentDisposition = src_obj_metadata.contentDisposition
  if override or not dst_obj_metadata.contentEncoding:
    dst_obj_metadata.contentEncoding = src_obj_metadata.contentEncoding
  if override or not dst_obj_metadata.contentLanguage:
    dst_obj_metadata.contentLanguage = src_obj_metadata.contentLanguage
  if override or not dst_obj_metadata.contentType:
    dst_obj_metadata.contentType = src_obj_metadata.contentType
  if override or not dst_obj_metadata.customTime:
    dst_obj_metadata.customTime = src_obj_metadata.customTime
  if override or not dst_obj_metadata.md5Hash:
    dst_obj_metadata.md5Hash = src_obj_metadata.md5Hash
  CopyCustomMetadata(src_obj_metadata, dst_obj_metadata, override=override)

def CopyCustomMetadata(src_obj_metadata, dst_obj_metadata, override=False):
  """Copies custom metadata from src_obj_metadata to dst_obj_metadata.

  Args:
    src_obj_metadata: Metadata from source object.
    dst_obj_metadata: Initialized metadata for destination object.
    override: If true, will overwrite metadata in destination object.
              If false, only writes metadata for values that don't already
              exist.
  """
  # TODO: Apitools should ideally treat metadata like a real dictionary instead
  # of a list of key/value pairs (with an O(N^2) lookup).  In practice the
  # number of values is typically small enough not to matter.
  # Work around this by creating our own dictionary.
  if (src_obj_metadata.metadata and
      src_obj_metadata.metadata.additionalProperties):
    if not dst_obj_metadata.metadata:
      dst_obj_metadata.metadata = apitools_messages.Object.MetadataValue()
    if not dst_obj_metadata.metadata.additionalProperties:
      dst_obj_metadata.metadata.additionalProperties = []
    dst_metadata_dict = {}
    for dst_prop in dst_obj_metadata.metadata.additionalProperties:
      dst_metadata_dict[dst_prop.key] = dst_prop.value
    for src_prop in src_obj_metadata.metadata.additionalProperties:
      if src_prop.key in dst_metadata_dict:
        if override:
          # Metadata values of '' mean suppress/remove this header.
          if src_prop.value is not None and not src_prop.value:
            dst_metadata_dict[src_prop.key] = None
          else:
            dst_metadata_dict[src_prop.key] = src_prop.value
      elif src_prop.value != '':  # pylint: disable=g-explicit-bool-comparison
        # Don't propagate '' value since that means to remove the header.
        dst_metadata_dict[src_prop.key] = src_prop.value
    # Rewrite the list with our updated dict.
    dst_obj_metadata.metadata.additionalProperties = []
    for k, v in six.iteritems(dst_metadata_dict):
      dst_obj_metadata.metadata.additionalProperties.append(
          apitools_messages.Object.MetadataValue.AdditionalProperty(key=k,
                                                                    value=v))

def PreconditionsFromHeaders(headers):
  """Creates bucket or object preconditions acccording to the provided headers.

  Args:
    headers: Dict of headers passed via gsutil -h

  Returns:
    gsutil Cloud API Preconditions object fields populated from headers, or None
    if no precondition headers are present.
  """
  return_preconditions = Preconditions()
  try:
    for header, value in headers.items():
      if GOOG_GENERATION_MATCH_REGEX.match(header):
        return_preconditions.gen_match = long(value)
      if GOOG_METAGENERATION_MATCH_REGEX.match(header):
        return_preconditions.meta_gen_match = long(value)
  except ValueError as _:
    raise ArgumentException('Invalid precondition header specified. '
                            'x-goog-if-generation-match and '
                            'x-goog-if-metageneration match must be specified '
                            'with a positive integer value.')
  return return_preconditions

def CreateNotFoundExceptionForObjectWrite(dst_provider,
                                          dst_bucket_name,
                                          src_provider=None,
                                          src_bucket_name=None,
                                          src_object_name=None,
                                          src_generation=None):
  """Creates a NotFoundException for an object upload or copy.

  This is necessary because 404s don't necessarily specify which resource
  does not exist.

  Args:
    dst_provider: String abbreviation of destination provider, e.g., 'gs'.
    dst_bucket_name: Destination bucket name for the write operation.
    src_provider: String abbreviation of source provider, i.e. 'gs', if any.
    src_bucket_name: Source bucket name, if any (for the copy case).
    src_object_name: Source object name, if any (for the copy case).
    src_generation: Source object generation, if any (for the copy case).

  Returns:
    NotFoundException with appropriate message.
  """
  dst_url_string = '%s://%s' % (dst_provider, dst_bucket_name)
  if src_bucket_name and src_object_name:
    src_url_string = '%s://%s/%s' % (src_provider, src_bucket_name,
                                     src_object_name)
    if src_generation:
      src_url_string += '#%s' % str(src_generation)
    return NotFoundException(
        'The source object %s or the destination bucket %s does not exist.' %
        (src_url_string, dst_url_string))

  return NotFoundException(
      'The destination bucket %s does not exist or the write to the '
      'destination must be restarted' % dst_url_string)

def CreateBucketNotFoundException(code, provider, bucket_name):
  return BucketNotFoundException('%s://%s bucket does not exist.' %
                                 (provider, bucket_name),
                                 bucket_name,
                                 status=code)

def CreateObjectNotFoundException(code,
                                  provider,
                                  bucket_name,
                                  object_name,
                                  generation=None):
  uri_string = '%s://%s/%s' % (provider, bucket_name, object_name)
  if generation:
    uri_string += '#%s' % str(generation)
  return NotFoundException('%s does not exist.' % uri_string, status=code)

def CheckForXmlConfigurationAndRaise(config_type_string, json_txt):
  """Checks a JSON parse exception for provided XML configuration."""
  try:
    xml.etree.ElementTree.fromstring(str(json_txt))
    raise ArgumentException('\n'.join(
        textwrap.wrap(
            'XML {0} data provided; Google Cloud Storage {0} configuration '
            'now uses JSON format. To convert your {0}, set the desired XML '
            'ACL using \'gsutil {1} set ...\' with gsutil version 3.x. Then '
            'use \'gsutil {1} get ...\' with gsutil version 4 or greater to '
            'get the corresponding JSON {0}.'.format(
                config_type_string, config_type_string.lower()))))
  except XmlParseError:
    pass
  raise ArgumentException('JSON %s data could not be loaded '
                          'from: %s' % (config_type_string, json_txt))

class LifecycleTranslation(object):
  """Functions for converting between various lifecycle formats.

    This class handles conversation to and from Boto Cors objects, JSON text,
    and apitools Message objects.
  """

  @classmethod
  def BotoLifecycleFromMessage(cls, lifecycle_message):
    """Translates an apitools message to a boto lifecycle object."""
    boto_lifecycle = boto.gs.lifecycle.LifecycleConfig()
    if lifecycle_message:
      for rule_message in lifecycle_message.rule:
        boto_rule = boto.gs.lifecycle.Rule()
        if rule_message.action and rule_message.action.type:
          if rule_message.action.type.lower() == 'delete':
            boto_rule.action = boto.gs.lifecycle.DELETE
          elif rule_message.action.type.lower() == 'setstorageclass':
            boto_rule.action = boto.gs.lifecycle.SET_STORAGE_CLASS
            boto_rule.action_text = rule_message.action.storageClass
        if rule_message.condition:
          if rule_message.condition.age is not None:
            boto_rule.conditions[boto.gs.lifecycle.AGE] = (str(
                rule_message.condition.age))
          if rule_message.condition.createdBefore:
            boto_rule.conditions[boto.gs.lifecycle.CREATED_BEFORE] = (str(
                rule_message.condition.createdBefore))
          if rule_message.condition.isLive is not None:
            boto_rule.conditions[boto.gs.lifecycle.IS_LIVE] = (
                # Note that the GCS XML API only accepts "false" or "true"
                # in all lower case.
                str(rule_message.condition.isLive).lower())
          if rule_message.condition.matchesStorageClass:
            boto_rule.conditions[boto.gs.lifecycle.MATCHES_STORAGE_CLASS] = [
                str(sc) for sc in rule_message.condition.matchesStorageClass
            ]
          if rule_message.condition.numNewerVersions is not None:
            boto_rule.conditions[boto.gs.lifecycle.NUM_NEWER_VERSIONS] = (str(
                rule_message.condition.numNewerVersions))
        boto_lifecycle.append(boto_rule)
    return boto_lifecycle

  @classmethod
  def BotoLifecycleToMessage(cls, boto_lifecycle):
    """Translates a boto lifecycle object to an apitools message."""
    lifecycle_message = None
    if boto_lifecycle:
      lifecycle_message = apitools_messages.Bucket.LifecycleValue()
      for boto_rule in boto_lifecycle:
        lifecycle_rule = (
            apitools_messages.Bucket.LifecycleValue.RuleValueListEntry())
        lifecycle_rule.condition = (apitools_messages.Bucket.LifecycleValue.
                                    RuleValueListEntry.ConditionValue())
        if boto_rule.action:
          if boto_rule.action == boto.gs.lifecycle.DELETE:
            lifecycle_rule.action = (apitools_messages.Bucket.LifecycleValue.
                                     RuleValueListEntry.ActionValue(
                                         type='Delete'))
          elif boto_rule.action == boto.gs.lifecycle.SET_STORAGE_CLASS:
            lifecycle_rule.action = (apitools_messages.Bucket.LifecycleValue.
                                     RuleValueListEntry.ActionValue(
                                         type='SetStorageClass',
                                         storageClass=boto_rule.action_text))
        if boto.gs.lifecycle.AGE in boto_rule.conditions:
          lifecycle_rule.condition.age = int(
              boto_rule.conditions[boto.gs.lifecycle.AGE])
        if boto.gs.lifecycle.CREATED_BEFORE in boto_rule.conditions:
          lifecycle_rule.condition.createdBefore = (
              LifecycleTranslation.TranslateBotoLifecycleTimestamp(
                  boto_rule.conditions[boto.gs.lifecycle.CREATED_BEFORE]))
        if boto.gs.lifecycle.IS_LIVE in boto_rule.conditions:
          boto_is_live_str = (
              boto_rule.conditions[boto.gs.lifecycle.IS_LIVE].lower())
          if boto_is_live_str == 'true':
            lifecycle_rule.condition.isLive = True
          elif boto_is_live_str == 'false':
            lifecycle_rule.condition.isLive = False
          else:
            raise CommandException(
                'Got an invalid Boto value for IsLive condition ("%s"), '
                'expected "true" or "false".' %
                boto_rule.conditions[boto.gs.lifecycle.IS_LIVE])
        if boto.gs.lifecycle.MATCHES_STORAGE_CLASS in boto_rule.conditions:
          for storage_class in (
              boto_rule.conditions[boto.gs.lifecycle.MATCHES_STORAGE_CLASS]):
            lifecycle_rule.condition.matchesStorageClass.append(storage_class)
        if boto.gs.lifecycle.NUM_NEWER_VERSIONS in boto_rule.conditions:
          lifecycle_rule.condition.numNewerVersions = int(
              boto_rule.conditions[boto.gs.lifecycle.NUM_NEWER_VERSIONS])
        lifecycle_message.rule.append(lifecycle_rule)
    return lifecycle_message

  @classmethod
  def JsonLifecycleFromMessage(cls, lifecycle_message):
    """Translates an apitools message to lifecycle JSON."""
    return str(encoding.MessageToJson(lifecycle_message)) + '\n'

  @classmethod
  def JsonLifecycleToMessage(cls, json_txt):
    """Translates lifecycle JSON to an apitools message."""
    try:
      deserialized_lifecycle = json.loads(json_txt)
      # If lifecycle JSON is the in the following format
      # {'lifecycle': {'rule': ... then strip out the 'lifecycle' key
      # and reduce it to the following format
      # {'rule': ...
      if 'lifecycle' in deserialized_lifecycle:
        deserialized_lifecycle = deserialized_lifecycle['lifecycle']

      lifecycle = encoding.DictToMessage(
          deserialized_lifecycle or {}, apitools_messages.Bucket.LifecycleValue)
      return lifecycle
    except ValueError:
      CheckForXmlConfigurationAndRaise('lifecycle', json_txt)

  @classmethod
  def TranslateBotoLifecycleTimestamp(cls, lifecycle_datetime):
    """Parses the timestamp from the boto lifecycle into a datetime object."""
    return datetime.datetime.strptime(lifecycle_datetime, '%Y-%m-%d').date()

class CorsTranslation(object):
  """Functions for converting between various CORS formats.

    This class handles conversation to and from Boto Cors objects, JSON text,
    and apitools Message objects.
  """

  @classmethod
  def BotoCorsFromMessage(cls, cors_message):
    """Translates an apitools message to a boto Cors object."""
    cors = boto.gs.cors.Cors()
    cors.cors = []
    for collection_message in cors_message:
      collection_elements = []
      if collection_message.maxAgeSeconds:
        collection_elements.append(
            (boto.gs.cors.MAXAGESEC, str(collection_message.maxAgeSeconds)))
      if collection_message.method:
        method_elements = []
        for method in collection_message.method:
          method_elements.append((boto.gs.cors.METHOD, method))
        collection_elements.append((boto.gs.cors.METHODS, method_elements))
      if collection_message.origin:
        origin_elements = []
        for origin in collection_message.origin:
          origin_elements.append((boto.gs.cors.ORIGIN, origin))
        collection_elements.append((boto.gs.cors.ORIGINS, origin_elements))
      if collection_message.responseHeader:
        header_elements = []
        for header in collection_message.responseHeader:
          header_elements.append((boto.gs.cors.HEADER, header))
        collection_elements.append((boto.gs.cors.HEADERS, header_elements))
      cors.cors.append(collection_elements)
    return cors

  @classmethod
  def BotoCorsToMessage(cls, boto_cors):
    """Translates a boto Cors object to an apitools message."""
    message_cors = []
    if boto_cors.cors:
      for cors_collection in boto_cors.cors:
        if cors_collection:
          collection_message = apitools_messages.Bucket.CorsValueListEntry()
          for element_tuple in cors_collection:
            if element_tuple[0] == boto.gs.cors.MAXAGESEC:
              collection_message.maxAgeSeconds = int(element_tuple[1])
            if element_tuple[0] == boto.gs.cors.METHODS:
              for method_tuple in element_tuple[1]:
                collection_message.method.append(method_tuple[1])
            if element_tuple[0] == boto.gs.cors.ORIGINS:
              for origin_tuple in element_tuple[1]:
                collection_message.origin.append(origin_tuple[1])
            if element_tuple[0] == boto.gs.cors.HEADERS:
              for header_tuple in element_tuple[1]:
                collection_message.responseHeader.append(header_tuple[1])
          message_cors.append(collection_message)
    return message_cors

  @classmethod
  def JsonCorsToMessageEntries(cls, json_cors):
    """Translates CORS JSON to an apitools message.

    Args:
      json_cors: JSON string representing CORS configuration.

    Raises:
      ArgumentException on invalid CORS JSON data.

    Returns:
      List of apitools Bucket.CorsValueListEntry. An empty list represents
      no CORS configuration.
    """
    deserialized_cors = None
    try:
      deserialized_cors = json.loads(json_cors)
    except ValueError:
      CheckForXmlConfigurationAndRaise('CORS', json_cors)

    if not isinstance(deserialized_cors, list):
      raise ArgumentException(
          'CORS JSON should be formatted as a list containing one or more JSON '
          'objects.\nSee "gsutil help cors".')

    cors = []
    for cors_entry in deserialized_cors:
      cors.append(
          encoding.DictToMessage(cors_entry,
                                 apitools_messages.Bucket.CorsValueListEntry))
    return cors

  @classmethod
  def MessageEntriesToJson(cls, cors_message):
    """Translates an apitools message to CORS JSON."""
    json_text = ''
    # Because CORS is a MessageField, serialize/deserialize as JSON list.
    json_text += '['
    printed_one = False
    for cors_entry in cors_message:
      if printed_one:
        json_text += ','
      else:
        printed_one = True
      json_text += encoding.MessageToJson(cors_entry)
    json_text += ']\n'
    return json_text

def S3MarkerAclFromObjectMetadata(object_metadata):
  """Retrieves GUID-marked S3 ACL from object metadata, if present.

  Args:
    object_metadata: Object metadata to check.

  Returns:
    S3 ACL text, if present, None otherwise.
  """
  if (object_metadata and object_metadata.metadata and
      object_metadata.metadata.additionalProperties):
    for prop in object_metadata.metadata.additionalProperties:
      if prop.key == S3_ACL_MARKER_GUID:
        return prop.value

def AddS3MarkerAclToObjectMetadata(object_metadata, acl_text):
  """Adds a GUID-marked S3 ACL to the object metadata.

  Args:
    object_metadata: Object metadata to add the acl to.
    acl_text: S3 ACL text to add.
  """
  if not object_metadata.metadata:
    object_metadata.metadata = apitools_messages.Object.MetadataValue()
  if not object_metadata.metadata.additionalProperties:
    object_metadata.metadata.additionalProperties = []

  object_metadata.metadata.additionalProperties.append(
      apitools_messages.Object.MetadataValue.AdditionalProperty(
          key=S3_ACL_MARKER_GUID, value=acl_text))

def UnaryDictToXml(message):
  """Generates XML representation of a nested dict.

  This dict contains exactly one top-level entry and an arbitrary number of
  2nd-level entries, e.g. capturing a WebsiteConfiguration message.

  Args:
    message: The dict encoding the message.

  Returns:
    XML string representation of the input dict.

  Raises:
    Exception: if dict contains more than one top-level entry.
  """
  if len(message) != 1:
    raise Exception('Expected dict of size 1, got size %d' % len(message))

  name, content = message.items()[0]
  element_type = xml.etree.ElementTree.Element(name)
  for element_property, value in sorted(content.items()):
    node = xml.etree.ElementTree.SubElement(element_type, element_property)
    node.text = value
  return xml.etree.ElementTree.tostring(element_type)

class LabelTranslation(object):
  """Functions for converting between various Label(JSON)/Tags(XML) formats.

  This class handles conversion to and from Boto Tags objects, JSON text, and
  apitools LabelsValue message objects.
  """

  @classmethod
  def BotoTagsToMessage(cls, tags):
    label_dict = {}
    for tag_set in tags:
      label_dict.update(dict((i.key, i.value) for i in tag_set))
    return cls.DictToMessage(label_dict) if label_dict else None

  @classmethod
  def BotoTagsFromMessage(cls, message):
    label_dict = json.loads(cls.JsonFromMessage(message))
    tag_set = TagSet()
    for key, value in six.iteritems(label_dict):
      if value:  # Skip values which may be set to None.
        tag_set.add_tag(key, value)
    tags = Tags()
    tags.add_tag_set(tag_set)
    return tags

  @classmethod
  def JsonFromMessage(cls, message, pretty_print=False):
    json_str = encoding.MessageToJson(message)
    if pretty_print:
      return json.dumps(json.loads(json_str),
                        sort_keys=True,
                        indent=2,
                        separators=(',', ': '))
    return json_str

  @classmethod
  def DictToMessage(cls, label_dict):
    return encoding.DictToMessage(label_dict,
                                  apitools_messages.Bucket.LabelsValue)

class AclTranslation(object):
  """Functions for converting between various ACL formats.

    This class handles conversion to and from Boto ACL objects, JSON text,
    and apitools Message objects.
  """

  JSON_TO_XML_ROLES = {
      'READER': 'READ',
      'WRITER': 'WRITE',
      'OWNER': 'FULL_CONTROL',
  }
  XML_TO_JSON_ROLES = {
      'READ': 'READER',
      'WRITE': 'WRITER',
      'FULL_CONTROL': 'OWNER',
  }

  @classmethod
  def BotoAclFromJson(cls, acl_json):
    acl = ACL()
    acl.parent = None
    acl.entries = cls.BotoEntriesFromJson(acl_json, acl)
    return acl

  @classmethod
  # acl_message is a list of messages, either object or bucketaccesscontrol
  def BotoAclFromMessage(cls, acl_message):
    acl_dicts = []
    for message in acl_message:
      if message == PRIVATE_DEFAULT_OBJ_ACL:
        # Sentinel value indicating acl_dicts should be an empty list to create
        # a private (no entries) default object ACL.
        break
      acl_dicts.append(encoding.MessageToDict(message))
    return cls.BotoAclFromJson(acl_dicts)

  @classmethod
  def BotoAclToJson(cls, acl):
    if hasattr(acl, 'entries'):
      return cls.BotoEntriesToJson(acl.entries)
    return []

  @classmethod
  def BotoObjectAclToMessage(cls, acl):
    for entry in cls.BotoAclToJson(acl):
      message = encoding.DictToMessage(entry,
                                       apitools_messages.ObjectAccessControl)
      message.kind = 'storage#objectAccessControl'
      yield message

  @classmethod
  def BotoBucketAclToMessage(cls, acl):
    for entry in cls.BotoAclToJson(acl):
      message = encoding.DictToMessage(entry,
                                       apitools_messages.BucketAccessControl)
      message.kind = 'storage#bucketAccessControl'
      yield message

  @classmethod
  def BotoEntriesFromJson(cls, acl_json, parent):
    entries = Entries(parent)
    entries.parent = parent
    entries.entry_list = [
        cls.BotoEntryFromJson(entry_json) for entry_json in acl_json
    ]
    return entries

  @classmethod
  def BotoEntriesToJson(cls, entries):
    return [cls.BotoEntryToJson(entry) for entry in entries.entry_list]

  @classmethod
  def BotoEntryFromJson(cls, entry_json):
    """Converts a JSON entry into a Boto ACL entry."""
    entity = entry_json['entity']
    permission = cls.JSON_TO_XML_ROLES[entry_json['role']]
    if entity.lower() == ALL_USERS.lower():
      return Entry(type=ALL_USERS, permission=permission)
    elif entity.lower() == ALL_AUTHENTICATED_USERS.lower():
      return Entry(type=ALL_AUTHENTICATED_USERS, permission=permission)
    elif entity.startswith('project'):
      raise CommandException('XML API does not support project scopes, '
                             'cannot translate ACL.')
    elif 'email' in entry_json:
      if entity.startswith('user'):
        scope_type = USER_BY_EMAIL
      elif entity.startswith('group'):
        scope_type = GROUP_BY_EMAIL
      return Entry(type=scope_type,
                   email_address=entry_json['email'],
                   permission=permission)
    elif 'entityId' in entry_json:
      if entity.startswith('user'):
        scope_type = USER_BY_ID
      elif entity.startswith('group'):
        scope_type = GROUP_BY_ID
      return Entry(type=scope_type,
                   id=entry_json['entityId'],
                   permission=permission)
    elif 'domain' in entry_json:
      if entity.startswith('domain'):
        scope_type = GROUP_BY_DOMAIN
      return Entry(type=scope_type,
                   domain=entry_json['domain'],
                   permission=permission)
    raise CommandException('Failed to translate JSON ACL to XML.')

  @classmethod
  def BotoEntryToJson(cls, entry):
    """Converts a Boto ACL entry to a valid JSON dictionary."""
    acl_entry_json = {}
    # JSON API documentation uses camel case.
    scope_type_lower = entry.scope.type.lower()
    if scope_type_lower == ALL_USERS.lower():
      acl_entry_json['entity'] = 'allUsers'
    elif scope_type_lower == ALL_AUTHENTICATED_USERS.lower():
      acl_entry_json['entity'] = 'allAuthenticatedUsers'
    elif scope_type_lower == USER_BY_EMAIL.lower():
      acl_entry_json['entity'] = 'user-%s' % entry.scope.email_address
      acl_entry_json['email'] = entry.scope.email_address
    elif scope_type_lower == USER_BY_ID.lower():
      acl_entry_json['entity'] = 'user-%s' % entry.scope.id
      acl_entry_json['entityId'] = entry.scope.id
    elif scope_type_lower == GROUP_BY_EMAIL.lower():
      acl_entry_json['entity'] = 'group-%s' % entry.scope.email_address
      acl_entry_json['email'] = entry.scope.email_address
    elif scope_type_lower == GROUP_BY_ID.lower():
      acl_entry_json['entity'] = 'group-%s' % entry.scope.id
      acl_entry_json['entityId'] = entry.scope.id
    elif scope_type_lower == GROUP_BY_DOMAIN.lower():
      acl_entry_json['entity'] = 'domain-%s' % entry.scope.domain
      acl_entry_json['domain'] = entry.scope.domain
    else:
      raise ArgumentException('ACL contains invalid scope type: %s' %
                              scope_type_lower)

    acl_entry_json['role'] = cls.XML_TO_JSON_ROLES[entry.permission]
    return acl_entry_json

  @classmethod
  def JsonToMessage(cls, json_data, message_type):
    """Converts the input JSON data into list of Object/BucketAccessControls.

    Args:
      json_data: String of JSON to convert.
      message_type: Which type of access control entries to return,
                    either ObjectAccessControl or BucketAccessControl.

    Raises:
      ArgumentException on invalid JSON data.

    Returns:
      List of ObjectAccessControl or BucketAccessControl elements.
    """
    try:
      deserialized_acl = json.loads(json_data)

      acl = []
      for acl_entry in deserialized_acl:
        acl.append(encoding.DictToMessage(acl_entry, message_type))
      return acl
    except ValueError:
      CheckForXmlConfigurationAndRaise('ACL', json_data)

  @classmethod
  def JsonFromMessage(cls, acl):
    """Strips unnecessary fields from an ACL message and returns valid JSON.

    Args:
      acl: iterable ObjectAccessControl or BucketAccessControl

    Returns:
      ACL JSON string.
    """
    serializable_acl = []
    if acl is not None:
      for acl_entry in acl:
        if acl_entry.kind == 'storage#objectAccessControl':
          acl_entry.object = None
          acl_entry.generation = None
        acl_entry.kind = None
        acl_entry.bucket = None
        acl_entry.id = None
        acl_entry.selfLink = None
        acl_entry.etag = None
        serializable_acl.append(encoding.MessageToDict(acl_entry))
    return json.dumps(serializable_acl,
                      sort_keys=True,
                      indent=2,
                      separators=(',', ': '))

redpajama_set_name: RedPajamaGithub


text:
Flying Lizard Motorsports and Krohn Racing Partner for the Rolex 24 at Daytona
KBruCommunications December 29, 2015 0
In anticipation of an exciting 2016 season opening event, Flying Lizard Motorsports and Krohn Racing have joined forces for competition in IMSA WeatherTech SportsCar Championship's Rolex 24 at Daytona International Speedway. The Audi Sport customer racing team will run the No. 45 Audi R8 LMS, the same car that finished 2nd in the 2014 running of the event.
Flying Lizard Motorsports has previously raced the 24 Hours of Daytona seven times, earning three podiums and two pole positions. In 2014, the team celebrated a win at the iconic event, but four hours after the podium celebrations, a penalty on a competitor's car was reversed, reinstating the competitors as the winners. In 2015, the team returned with a strong lineup, but a problem in the first hour took the car back to the garage for 30 minutes. Upon returning, the team showed a strong, error free run, again completing all 24 hours of racing.
Krohn Racing founder Tracy Krohn created Krohn Racing in 2005, and entered the team into international competition in GRAND-AM Road Racing, the American Le Mans Series, and FIA World Endurance Championship. Krohn Racing has celebrated three podium finishes at the 24 Hours of Le Mans in 2007, 2009 and 2012.
With both Flying Lizard Motorsports and Krohn Racing having individually celebrated wins at the 12 Hours of Sebring and Petit Le Mans, both are still determinedly seeking their first victory at the 24 Hours of Daytona.
The collaboration of the two championship winning teams will feature an all-star driver line up of Tracy Krohn, Nic Jonsson, and Audi Sport customer racing drivers Pierre Kaffer and Christopher Haase.
Since Tracys Krohn's first year acting as a team owner and driver, he has been a part of an endurance race winning effort. In 2005, Krohn and co-driver Nic Jonsson clinched the overall win at the 6 Hours of Watkins Glen, and in 2011, Krohn celebrated class wins at the 12 Hours of Sebring and Petit Le Mans.
The 2016 season will mark Nic Jonsson's 26th year racing professionally, and more impressively, his 12th full season with Tracy Krohn. With such consistency being a rare find in motorsports, the two teammates will strengthen the already robust driver line up. The Swedish driver's resume is extensive, including experience in IndyCar, Touring cars and NASCAR. With a Rolex 24 best finish of 4th place, Jonsson has a clear determination to finish on the top step next month.
With an extensive career in endurance racing, as well as histories with Krohn Racing and Audi, German racer Pierre Kaffer is a solid fit to the Rolex 24 lineup. As part of a joint effort between Krohn Racing and Risi Competizione, Kaffer was a part of the 2009 24 Hours of Le Mans winning effort, and also holds multiple wins at the 12 Hours of Sebring and Petit Le Mans.
Also a former competitor of Flying Lizard Motorsports, Audi Sport customer racing driver Christopher Haase joins the team after coming in 3rd in the 2015 GTD championship, driving the Audi R8 LMS. The German driver is a two time winner at the 24 Hours of Nürburgring, one time winner at Petit Le Mans, and most recently, came in 2nd at the 2015 12 Hours of Sepang.
Although other competitors in the WeatherTech GTD class will be running the new Audi R8 LMS, the Flying Lizard will continue to run the same Audi R8 LMS as before, but upgraded to the homologated GT3 spec. Adding more aerodynamic grip, the car will run a larger rear wing, bigger front splitter, bigger dive planes and a different diffuser. Unlike the previous years, the car will also be allowed to run with ABS and traction control. Running the same engine and transmission that it ran last year in IMSA's GTD class, this is also the same configuration the team ran this month at the 25 Hours of Thunderhill, where the team ran issue free and finished on the top step over 56 other cars.
The official series test for the Rolex 24, the Roar Before the 24, will take place at Daytona International Speedway January 8-10. The official on track activities for the Rolex 24 at Daytona begin January 28, 2016.
Tracy Krohn
I'm really looking forward to getting back on track for the 24 Hours of Daytona and with joining Flying Lizard Motorsports. We've competed against them for many years and know they run a great operation. Last month we conducted a test with the Audi R8 LMS at Sonoma Raceway. This was the first time Nic and I have had the chance to drive the Audi and we were both very impressed. I feel very confident in our package heading into the Roar Before the 24. This particular car should be very good at Daytona, and we have an excellent driver lineup, so it should be a great event.
Nic Jonsson
Having the opportunity to join a team with such pedigree is great for both myself and Tracy. And to do that as a collaboration between the two teams makes it very strong. I have been racing against and with many of the Lizard guys over the years, and makes it a very easy transition, since we already know each other, and have great respect for what each one of us do. With the experience of endurance racing between the two teams, and specifically at Daytona, I'm really looking forward to the 24 hours of Daytona in 2016. The Audi R8 LMS is a new car to both myself and Tracy, but with the Lizards having a few years of experience along with great support from Audi, we know this is a great and winning package.
I'm also very excited to have the two Audi drivers in Christopher Haase and Pierre Kaffer. They both had a lot of success over the last couple of years here in the states. Pierre has obviously been racing for another manufacturer before, and Tracy and myself were teammates with Pierre, so he's going to be another familiar face in the mix. I feel very fortunate to have had the opportunity to race and have such great results over the years with the same teammate, and we plan on carry that on at the 24 in 2016.
Being a 24 hour race, at a very special and untraditional track lay out, it makes it for a lot of surprises, and will benefit the teams and drivers who will be patient, stay out of trouble, and understanding that, it's about making sure you take care of your equipment and that you in contention, when the sun comes up on Sunday morning.
Pierre Kaffer
I'm really looking forward to driving for Flying Lizard Motorsports for the first time. I've known the team for many years, for me it's one of the best in USA with such a strong history. The partnership together with Krohn Racing is just a great new combination. I can't wait to work together with Tracy, Nic and Christopher! I like racing at Daytona. I was close to a win two years ago, and last year we unfortunately had to retire with a technical issue in the lead. Daytona was always a good place and this year with the Audi R8 LMS, I'm sure we have the right car. I can't wait to drive.
I feel really excited to join Flying Lizard and Krohn Racing. These guys are great racers. We already know each other during the last two years of racing in the TUDOR championship, and we have a good relationship too. Our driver lineup is pretty good. Our car has a huge reliability and won already so many events during the last years around the world. Overall we have good package. The Rolex 24 will be like always a tough race. The biggest difference is now we all using now the GT3 Spec cars, and this is something new in 2016.
Darren Law // Flying Lizard Motorsports Program Manager
We are really looking forward to having Tracy Krohn and Nic Jonsson join us for this event. We have spent so many years as competitors, and we have a lot of respect for Tracy and Nic. It is nice to have them finally come on board and race with us. They both have a lot of experience in this type of racing and understand what it takes to win an event like this. We are also very grateful to have factory drivers Christopher Haase and Pierre Kaffer join us for this event. Both are very experienced and will complete a great driver lineup. To bring a brand new car with limited testing is risky for such a long event like this, so we are confident in our choice of last years car. Our car is proven, it is reliable, and we know its strengths and its weaknesses, which will help us to be better prepared.
About Flying Lizard Motorsports
Since its inception in 2004, Flying Lizard Motorsports has become an iconic team in the world of sports car racing. The California based team has celebrated six driver and team championships, as well as competed internationally at the 24 Hours of Le Mans eight times. The Lizards burst on the American Le Mans Series scene in 2004, competing in the GT class until 2012. In 2013, the team moved to the GTC class, still competing in legendary events such as the 12 Hours of Sebring and 24 Hours of Daytona. In 2014, the team expanded its program to include running two Audi R8 LMS in the TUDOR Championship, and in 2015, again expanded the program to include two Porsches in Porsche Club racing, and two McLaren 650S GT3s with K-PAX Racing in the World Challenge series. No matter the race series or race car, Flying Lizard Motorsports has proven to be a championship contender in sports car racing. For more information, visit www.lizardms.com. For additional photos and all behind-the-scenes updates, check us out on Facebook, Twitter, and Instagram.
About Audi of America and the Audi R8 LMS
Audi began a new chapter in 2009 with the introduction of the Audi Sport customer racing program. For the first time it was possible for motorsport customers to acquire a race car designed for customer racing events. Since its inception, the success of the R8 LMS has been significant throughout the GT3 racing format worldwide, including victory in the GT class in the 2013 edition of the Rolex 24 at Daytona. The Audi R8 LMS shares more than 50% of its parts with the Audi R8 street car including the naturally aspirated V10 5.2 Liter engine, the Audi Space Frame and a variety of other components.
Audi of America, Inc. and its U.S. dealers offer a full line of German-engineered luxury vehicles. AUDI AG is among the most successful luxury automotive brands globally. Audi was a top-performing luxury brand in Europe during 2012, and broke all-time company sales records in the U.S. Through 2016, AUDI AG will invest about $17 billion on new products and technologies.
Visit www.audiusa.com or www.audiusanews.com for more information regarding Audi vehicle and business issues.
Previous: Previous post: Toyo Tires and Flying Lizard Motorsports Secure Overall Victory at USAF 25 Hours of Thunderhill
Next: Next post: Starworks Motorsport Announces IMSA Full Season Lineup


text:
Pulse show on 112 Ukraine TV to discuss #Freedom_of_speech in Ukraine today
The main and only topic of today's broadcasting is #Freedom_of_sppech in Ukraine and results of the day-old consideration of the draft resolution on the appeal to the NSDC on the sanctions against 112 Ukraine and NewsOne in the Verkhovna Rada
Today, on October 5, the extra episode of the main political talk-show of Ukraine "Pulse" will be broadcasted by 112 Ukraine.
The main and only topic of today's broadcasting is #Freedom_of_sppech in Ukraine and results of the day-old consideration of the draft resolution on the appeal to the National Security and Defense Council of Ukraine (NSDC) on the sanctions against 112 Ukraine and NewsOne in the Verkhovna Rada.
Related: Sanctions appeal against 112 Ukraine, NewsOne not sent to National Security and Defence Council
Hosts Volodymyr Poluyev and Anna Stepanets will seek for the explanations of what happened, particularly, from the MPs who voted for the appeal to the NSDC and discuss the situation with the experts.
MPs Olexander Opanasenko, Ivan Krulko, Olexander Vilkul, Boryslav Rosenblat, Ihor Mosiychuk, Yury Pavlenk, Oleg Barna and Yury Derevianko will be the guests.
Related: Today they ban Ukraine's TV channels, tomorrow run for president under democratic slogans
Also, Chief Editor of 112 Ukraine Pavlo Kuzheev, journalist Oleksy Mustafin, Producer-General of NewsOne TV Channel Vasyl Holovanov, political scientists Vadym Karasev and Ruslan Bortnik , ex-Prosecutor General Sviatoslav Piskun, ex-Justice Minister Oleksandr Lavrynovych, host Petro Maga, political tactitians Dmytro Raimov and Volodymyr Tsybulko, journalist Andry Palchevsky, ex-MP Ihor Myroshnychenko, journalist Volodymyr Boiko, lawyer Vasyl Smetana and political expert Valentyn Hladkykh will join the discussion.
As usual the audience will be able to actively participate in the discussion and ask the guests questions.
Related: British MP slams pressure on 112 Ukraine, NewsOne TV channels
Earlier, Oleksandr Turchynov, the Secretary of National Defense Council, said that the appeal of the Ukrainian Parliament to the National Security and Defense Council of Ukraine concerns only the founders of 112 Ukraine and NewsOne TV channels.
Ukraine's Verkhovna Rada urges the country's National Security and Defense Council of Ukraine to introduce sanctions against several Ukrainian TV channels. 229 MPs supported the draft law No. 9157 on "Approval of recommendations to introduce personal special economic sanctions and other restrictive measures (sanctions)".
Related: Parliament decision to sanction 112 Ukraine, NewsOne TV channels violates freedom of speech, - MP
CEO of 112 Ukraine TV channel Yegor Benkendorf stated that the attempt to stop the operation of 112 Ukraine is a part of a large-scale process and concerns an unsatisfactory situation with the respect of freedom of speech in Ukraine. According to him, 112 Ukraine TV channel has to confirm the impossibility to protect its rights independently by legal tools, and soon, it might lead to cessation of the broadcasting.
The appeal was sent to the President of the European Commission Donald Tusk, High Representative of the European Union for Foreign Affairs and Security Policy Federica Mogherini, the Secretary General of the Council of Europe Thorbjørn Jagland, the President of the Parliamentary Assembly of the Council of Europe Liliane Maury-Pasquier, President of the Committee of Ministers of the Council of Europe Marija Pejčinović Burić, United Nations High Commissioner for Human Rights Michelle Bachelet, Coordinator of the Europe and Central Asia Program of the Committee to Protect Journalists Nina Ognianova, General Secretary of the International Federation of Journalists Anthony Bellanger.
Moreover, the appeals were sent to the international organizations Human Rights Watch, Freedom House, Amnesty International, Reporters Without Borders and European Federation of Journalists.
Related: We hope for support of international partners, - 112 Ukraine TV channel's lawyer
112 Ukraine TV channel emphasizes again that it was following the principles of the journalistic work, giving an opportunity to express one's opinion for all the Ukrainian politicians, the representatives of the governmental bodies and independent experts during its existence. Also, the channel does not avoid covering acute political and social issues, and such position of the TV channel cases and will cause opposition from individual politicians and political forces.
The staff of 112 Ukraine TV channel insists that the steps made by the Ukrainian Parliament, which aim to apply sanctions against 112 Ukraine TV channel are nothing but a political decision; there is not enough evidence to make such decision, which badly lacks argumentation and may be considered unconstitutional.
freedom of speech 112 Ukraine TV channel newsone The Pulse (TV show) freedom_of_speech


Craft Rebellion - Discover fresh craft beers delivered to you. Craft Rebellion - Discover fresh craft beers delivered to you.
great craft beers as we do.
can bring joy to more offices around the UK.
Now bringing you great Beer, Soda, Cider & Wine.
The UK craft beer market continues to expand and the team at DeskBeers is growing to ensure our business customers continue to get access to these great beers, sodas, ciders and wine. Martin has decided to take the discovery of great beers to a new continent. Just like the UK and the US, Canada is going through a craft beer revolution. Whilst the sale of beer is more tightly controlled many breweries are springing up all over the country to sate the beer consumers desire for exciting new brews.
Unfortuately this means that there will be no more consumer deliveries.
However all is not lost, you can still follow Martin's discovery of new beers.


From the name, you might expect The Butcher's Daughter to be a meat emporium of some kind. But, no. This joint is all about plants, vegetables and other meat-free marvels. And it's everything you'd hope for, if you've been to one of the other outposts in New York. Painted white brick as far as the eye can see, festooned with draping greenery and blonde wood. There are shelves heavy with wine, wicker baskets and copper detailing. And, of course, menus that account for every meal of the day, filled with moreish dishes, fresh juices and smoothies, and hot drinks ranging from straightforward coffees and teas to "wellness lattes".
At Butcher's Daughter, you can start the day with a Solar Power smoothie (avocado, pineapple, coconut, kale, coriander and hemp protein) or, if you're in need, the Hangover Killer juice (young Thai coconut, yuzu, pineapple, chili and coriander). Maybe a fresh-baked pastry, or the so-called "Best Egg Sandwich", which, with farm eggs and homemade English muffin toast, baby kale, cheddar and harissa mayo, could actually be the best one we've tried.
Moving on through the day, diners at The Butcher's Daughter will find a sweeping range of vegetarian, vegan, and gluten-free dishes on offer. We're talking everything from daily market stone-oven pizzas and pad Thai to salted caramel affogato. There are salads, wraps, "elixir" shots of pure veg-based goodness, handmade pastas and more. And the best thing? Not only will you leave feeling sated and reeling from a rush of great food, but you'll be seriously, healthily nourished to boot.


text:
Lely Industries N.V. is a Dutch agricultural machine and robots manufacturer which is based in Maassluis, the Netherlands. It is considered as one of the leading dairy robot manufacturers.

History
The company was founded in 1948 by the Lely brothers, Cornelis van der Lely and Arij van der Lely, in Maassluis.

In 2012, the company acquired Aircon GmbH and subsequently renamed it as Lely Aircon B.V.

At the end of 2016, Lely ceased tipper production in Waldstetten.

In March 2017, the sale of the forage harvesting technology division with the plants in Waldstetten (loader wagons) and Wolfenbüttel (baling presses) to AGCO was announced.

In 2019, the company milking system reached the finals of 2019 European Inventor Award.

Robots
 Lely Astronaut A4
 Lely Vector
 Lely Juno

External links
Official website

See also
 Automated milking

Reference

Dutch brands
Dutch companies established in 1948
Manufacturing companies established in 1948
Agricultural machinery manufacturers of the Netherlands
Dairy farming equipment manufacturers
Companies based in South Holland
Maassluis

redpajama_set_name: RedPajamaWikipedia