text:
Patriots Offseason Coverage
Coming off his 13th NFL season, Patriots quarterback Brian Hoyer reportedly not yet willing to call it a career
Related: Devin McCourty reportedly not ready to retire yet, plans to play in 2022
By Bernd Buchmasser@BerndBuchmasser Feb 4, 2022, 6:00am EST
Share All sharing options for: Coming off his 13th NFL season, Patriots quarterback Brian Hoyer reportedly not yet willing to call it a career
Photo by Fred Kfoury III/Icon Sportswire via Getty Images
Brian Hoyer has had a successful career considering that he entered the league as an undrafted free agent. He started a combined 40 games since 2009 and won a Super Bowl backing up the greatest quarterback of all time, Tom Brady.
At 36, Hoyer following Brady into retirement would not be a surprise. However, it appears the veteran quarterback is not willing to take that step just yet: according to USA Today's Henry McKenna, Hoyer does not have any plans to retire this offseason.
That does not automatically mean he will have a spot on an NFL roster this season. Hoyer, after all, is headed towards unrestricted free agency.
That said, there is a chance the New England Patriots will bring him back on another low-cost contract. Re-signing Hoyer after he served as Mac Jones' primary backup throughout the 2021 season would make sense, not just because of his previous role: the Patriots also lost both offensive coordinator Josh McDaniels and assistant quarterbacks coach Bo Hardegree to the Las Vegas Raiders this offseason.
Retaining Hoyer would give New England and its second-year passer some stability in its quarterback room. The veteran deciding to continue his career would be the first step towards that happening.
A rookie free agent signing by the Patriots in 2009, Hoyer spent time with eight different franchises throughout his career. He returned to New England twice, serving as a backup to Brady in 2017 and 2018 and to Cam Newton in 2020.
The team signed him to a one-year contract last spring, and he went on to serve as its QB2 behind rookie Mac Jones and ahead of third-year man Jarrett Stidham. Hoyer finished his 13th NFL season with five in-game appearances, going 9-for-11 as a passer for 227 yards and a touchdown.


1 What is important in national dysphagia diet level 3?
2 What benefits do you get from national dysphagia diet level 3?
3 What you need to be ready when using national dysphagia diet level 3.
4 Important when using national dysphagia diet level 3.
national dysphagia diet level 3 helps in many cases.
What is important in national dysphagia diet level 3?
Repeat the national dysphagia diet level 3 several times a year.
What benefits do you get from national dysphagia diet level 3?
What you need to be ready when using national dysphagia diet level 3.
Important when using national dysphagia diet level 3.
Be sure to use the national dysphagia diet level 3 under the supervision of your doctor.
We recommend that you try national dysphagia diet level 3. Do it!


Buying a franchise is a big commitment, not to mention an enormous investment. Because of that, it's important that interested prospects are weighing all the pros and cons that exist. That's even more so the case in 2017.
In February's issue of Franchising World, franchise attorney Harold Kestenbaum shared his advice with hopeful franchisees in "Buying a franchise in 2017? Here's what you need to know." Read Harold's piece here!


The selection of an IT consultant in Los Angeles is a decision that shouldn't be taken lightly. Some IT consultants will promise comprehensive support and deliver a handful of services. Others will guarantee around-the-clock service, only to put your needs on the back burner. The key is to find a reliable consultant with service dexterity and a willingness to assist when an emergency strikes. Pinpointing such a provider is much easier said than done.
Too many business owners and managers make the critical mistake of assuming each IT consultant is the same. IT companies might promise similar services, but in reality, the end result is almost always strikingly different.
Each provider has unique personnel, capabilities, services, prices, and quality. The key is to get a firm gauge on each prospect's merit by way of referrals, web reviews, and word-of-mouth evaluations. Talk with locals who have done business with prospective IT consultants and find out how those relationships worked out. Those who perform their due diligence will stand a much better chance of allying with an IT company worth its keep.
Some IT consultants have no shame in claiming to offer every possible type of tech assistance under the sun, only to fall woefully short. Verify that prospects are certified across several vendors and all the latest technologies. True IT gurus know the ins and outs of the cloud, network security, colocation, web hosting etc.
Furthermore, the IT consultant in Los Angeles that you settle on should have personnel depth. The right prospect will have enough staff to handle all sorts of nuanced IT challenges even in those instances when the most experienced staff members are on vacation or sick.
Each discussion you have with an IT consultant should be centered on your business. The best IT consultants focus on client needs and demands. Nothing should get in the way of providing custom tailored IT service that boosts the client's efficiency and ultimately, the profit margin. If you feel as though an IT consultant doesn't listen when you speak about the details of your organization, move on to a new candidate.
Don't accept a one-size-fits-all IT service solution. Furthermore, you shouldn't be content with constant tech upgrades. Don't pay for these additions unless you are 100% positive that they're a proper fit for your business operations and goals.
Most IT consultants will talk a big game yet many will fail to follow through. This is precisely why it's prudent to obtain all service promises in writing. Each IT service should be clearly defined. The cost of these services should also be put in writing before a business relationship is established. Everything from service parameters to help desk assistance availability, promised response times, and the duration of service must be provided in writing.
At Integritechs, our IT consultant in Los Angeles follows through on all promises. We're here for you when emergency situations arise. Whether you need network support, assistance with hardware or software challenges or anything else related to tech challenges, we can help. Contact us today for an initial consultation.


Tableau Public 7.0 is here!
We've just released Tableau Public 7.0, and jam-packed it with new features.
You can see two of the biggest – filled maps and area charts – in the visualization below.
Filled maps are a beautiful, easy to understand way of seeing geographic data.
Area charts let you see simultaneously how both the individual elements of your data and the sum of their parts change over time.
There are lots of other improvements, including maps that wrap and automatically center themselves on your data, smarter place names (if you have data with "South Korea," "Republic of Korea," or "S. Korea" don't worry, it will all end up on the right place on your map), and multiple mark types on maps so you can look at two levels of data in the same view.
Mapping with multiple mark types (pie charts on filled maps).
We've also made Tableau Public easier to use with an improved interface and better training resources.
Training: We've revamped our training videos, dividing them into specific problems and actions so you can get answers to your questions faster. Check out our new training page.
We can't wait to see your new 7.0 vizes on the web. Tweet us your new vizes at @tableau – we love to see them!
I'd love to play with this.
I'd love to play with this. Anyway to do it on a Mac?
I'll try it on my first infographic.
I'm about to abandon PCs and the only program that's keeping me from doing it is Tableau. I know about running Tableau in a box but it is too slow.
Please release a Mac version.
I put my voice as well. A MAC version is a MUST!! If Tableau move to Mac plataform would have a great audience- including myself.
I was sold today, went to purchase and realized that there was no Mac version. Now I'm off to find something else.
If in numbers there is strength, then count my vote in for a MAC version, puh-leeease!
Well, again ... is a Mac version coming up soon (running Windows in a Mac just cause of Tableau it's not a real option)!
I dont know where this site makers have got the MAPs from, but I am sorry to say that they have commited a blunder. In the map of central asia/africa and europe (combined) a part of the "Jammu And Kashmir" state of India is wrongly shown as a part of pakistan. Pakistan has illeagly occupied the part and this matter is the major cause of political tension in Asia.
I request the site owners to kindly mend this. At least show it as a 'disputed territory' if not a part of the original country!
Utterly depressed. Bought a MacBook this week and the first thing I planned to instal was Tableau Public. Only to discover it doesn't work on Macs. PLEASE LISTEN TO THE DEMAND FOR YOUR GREAT WORK!
A couple years ago, I actually got my employer to buy Parallels and Windows 7 just to use Tabeau Free. Tableau was great, Parallels and Windows 7, not so much. My Mac became slow and weird and not worth it. Haven't used Tableau since. Really wish I could use it again. You have such a great product, but are alienating a huge portion of the population. Thought you'd have a Mac version by now, a few years later! All we can do is ask and hope you respond. Thanks.
Please, please hurry! The virtual environment is not practical for those of us running multiple applications at once and your product is too good to leave out of the Mac mainstream! Stop thinking and start coding.
A while back I gave up on clamouring for a MAC version. but hearing the clamouring and the fact that I'm using it again (on a borrowed windows machine) has inspired me to clamour some more.
Bring me my MAC version of Tableau!
Another vote here for a Mac version. Tableau on a Mac with Adobe Creative Suite would be a powerful combination.
Need a Mac version please !!!!!!
I NEED A Mac Version,Please.
ONE MORE REQUEST FOR THE MAC version!!!!
Really, STILL no mac version?
Really, STILL no mac version? Why do we have to beg?
Patiently awaiting you MAC version of Tableau. I hope there is some progress!
hi all - joining the chorus, mac version please.


text:
[ January 15, 2021 ] Samsung Galaxy Buds Pro review: The new best	Android
[ January 15, 2021 ] Fiat Chrysler's merger with France's PSA adds uncertainty to Peugeot's return to U.S., brand chief says	Cars
[ January 15, 2021 ] Persona 5 Strikers Preview: A Mixed Spinoff	Gaming
[ January 15, 2021 ] European IT providers struggle to capitalise on continent-wide growth in cloud demand	Internet
HomeGamingPlayStation 4 Slim Review: The Default Choice
PlayStation 4 Slim Review: The Default Choice
April 30, 2020 admin Gaming 0
PlayStation 4 Slim 1TB Console
"Now slimmer than ever, the refreshed PlayStation 4 fortifies Sony's iconic gaming platform."
Faster Wi-Fi can make a big difference
Smaller chassis with fun design
Same great PS4 game library
More affordable than ever
No more optical port
More powerful PS4 console also available
Three years after the launch of the PlayStation 4, Sony revisited its aging console to give it a new lease on life. As with previous PlayStations, the refreshed console has a slimmer new look, a few new features, and even some minor internal upgrades.
Unlike past generations, however, the new version of the console came at a tumultuous time for the PlayStation brand. There are currently not one but three new PlayStation devices: this revised PlayStation 4, a 4K-compatible version of the PS4 called the PlayStation 4 Pro, and a PlayStation VR headset that will work in conjunction with any PlayStation 4 device. Not to mention, the PS5 that will kick off the next generation of consoles.
The "Slim" might appear underwhelming beside such ambitious brothers. It's designed more to lure in players who haven't bought a modern console yet than to appeal to current PS4 owners. Nobody wants to buy the lesser launch console, after all.
If you have strong feelings about the PlayStation 4 — good or bad — this console isn't going to change your mind. Other than a thinner figure, it has only one or two notable changes over the original model. The most important elements — its processing power, the feel of its controller in your hand, the library of games available on the PlayStation Store — have not changed. While the new PlayStation 4 is "better" than the original, the difference isn't necessarily worth any additional investment, especially with a more powerful version on the market as well.
PlayStation gets a "fun" makeover
The most noticeable changes made to the new PlayStation 4 are going to be seen, not felt while you play.
On a functional level, the new console is considerably smaller than the original PlayStation 4, just over two-thirds the total size of the original PS4. It's also a bit lighter: The Slim weighs 4.6 pounds, as opposed to the original's 6.2 pounds.
More important, the Slim has received an aesthetic overhaul. The PS4's distinctive shape, a sharp, slanted parallelogram, has been slightly softened with rounded corners. In front, the disc drive and two USB ports are now somewhat hidden in a shallow indent. On top, the console is branded with the PlayStation logo. Underneath, the console rests on "feet" shaped like the triangles, circles, and exes found on the console's buttons.
The power and eject buttons, initially a pair of thin, black buttons on the front, are now much smaller and rest on the "lip" of the console in front of the disc drive. A large indicator light, which ran along the top of the console, has been removed. The light, which lets you know when the console is powering up or down, can now be seen in a small series of dots on the console's power button.
If you already own a PlayStation 4, there are few reasons to upgrade to a PlayStation 4 Slim.
The DualShock 4 controller has received a slight makeover, as well. The touchpad is now translucent, allowing a bar of light from the console's colorful indicator light to shine through. While you won't notice the change too often unless you routinely hold the controller in front of your face, it does provide easier access to the light at a glance. And the back panel, analog sticks, and direction pad buttons are now gray, rather than black.
While each change feels slight individually, together, they make the PS4 feel less self-serious than the original model. You get the sense that this product, while a substantial piece of technology, is meant for play, not business. The long light stripe on the console's top had lent the console a premium feel and a bit of flair, overall the new console looks nice and maintains a lower profile. People looking for it will enjoy its attention to detail; others won't notice as it fades into a shelf of routers, streaming devices, and other set-top boxes.
Wi-Fi Friendly
The most substantial improvement to the PlayStation 4 — the one reason you might consider buying one over the original — is its upgraded Wi-Fi compatibility. The Slim now supports 802.11ac Wi-Fi, which should lead to faster download speeds and more stability playing online for those whose routers support it. In my New York apartment, I was finally able to play games online over Wi-Fi, rather than by connecting through an Ethernet cable.
There's one other system change most people won't notice: with the Slim redesign, the PlayStation 4 loses its optical out port. If that news doesn't immediately make you scream, then it doesn't matter to you at all. The optical out is used for high-end home theater systems, and it will not make a difference for the majority of players.
The PlayStation 4 features a one-year warranty from the manufacturer, beginning the day the console is purchased.
Thanks to some minor tweaks and internal upgrades, the PlayStation 4 maintains its place as one of, if not the premier dedicated gaming platform. If you're looking to play some video games and don't plan to sweat the small stuff, you've come to the right place.
Not right now, and likely not until the next generation releases.
The Nintendo Switch is an excellent console, but it's hard to call it an alternative. The Switch can be used as a handheld or docked console. To do that, it compromises on visual quality. Nintendo's console also has a far different game library, so your choice depends on what you want to play.
Microsoft's Xbox One X, however, is clearly a step behind the PlayStation 4, despite being much more powerful. Some gamers may still prefer it (if you're a serious Gears fan, for example), but most will be better off sticking to Sony's console.
That said, though, the PlayStation 5 is almost here, and you might be better off waiting for it, as it will play many of the same games on its system right at launch.
The PlayStation 4 is nearing the end of its life, as the PlayStation 5 will release at the end of 2020, so long as production isn't affected. If you don't mind being a generation behind, however, the hardware itself should last for years, perhaps decades, with a massive library full of excellent games.
Maybe, if you don't already own a PS4. The PlayStation 4 Slim is the most affordable version of this generation's most popular console and, therefore, a great way to experience all of the amazing games this generation on a budget. However, if you can wait a bit and have the money to do so, you might just want to wait for the PS5 this holiday season.
This article was last updated by Digital Trends contributor Cody Perez on April 28, 2020.
Smartphone shipments dropped 13% globally, and COVID-19 is to blame – TechCrunch
Visteon near break-even in Q1 despite pandemic hit
Fiat Chrysler's merger with France's PSA adds uncertainty to Peugeot's return to U.S., brand chief says
Persona 5 Strikers Preview: A Mixed Spinoff
European IT providers struggle to capitalise on continent-wide growth in cloud demand
Cancelled Star Wars Ragtag game details surface
From Eurogamer: "A former producer on Amy Hennig's cancelled Star [...]
How to enable and disable a screensaver on PS4
Screensavers are something many folks are familiar with from an [...]
Later Daters Nintendo Switch Review – Sequential Planet
Dating simulation games may not be as mainstream as other [...]
Best true wireless earbuds under Rs 10,000 in India, for May 2020
A few years ago, Apple announced AirPods which created a [...]

redpajama_set_name: RedPajamaCommonCrawl


text:
Review of the WATERS Network Science Plan (2010)
Chapter: Front Matter
PDF FREE Download Paperback $29.00 Add to Cart Ebook $23.99 Add to Cart
Page i Share Cite
Suggested Citation:"Front Matter." National Research Council. 2010. Review of the WATERS Network Science Plan. Washington, DC: The National Academies Press. doi: 10.17226/12898.
REVIEW OF THE WATERS NETWORK SCIENCE PLAN
Committee on the Review of Water and Environmental Research Systems (WATERS) Network
Water Science and Technology Board
NATIONAL RESEARCH COUNCIL
OF THE NATIONAL ACADEMIES
THE NATIONAL ACADEMIES PRESS
www.nap.edu
Page ii Share Cite
500 Fifth Street, N.W.
NOTICE: The project that is the subject of this report was approved by the Governing Board of the National Research Council, whose members are drawn from the councils of the National Academy of Sciences, the National Academy of Engineering, and the Institute of Medicine. The members of the committee responsible for the report were chosen for their special competences and with regard for appropriate balance.
Support for this study was provided by the National Science Foundation under grant number CBET-0715260. Any opinions, findings, or conclusions and recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the organizations or agencies that provided support for the project.
International Standard Book Number-13: 978-0-309-15313-3
International Standard Book Number-10: 0-309-15313-1
Additional copies of this report are available from the
National Academies Press,
500 5th Street, N.W., Lockbox 285, Washington, DC 20055; (800) 624-6242 or (202) 334-3313 (in the Washington metropolitan area); Internet, http://www.nap.edu.
Copyright 2010 by the National Academy of Sciences. All rights reserved.
Printed in the United States of America.
Page iii Share Cite
The National Academy of Sciences is a private, nonprofit, self-perpetuating society of distinguished scholars engaged in scientific and engineering research, dedicated to the furtherance of science and technology and to their use for the general welfare. Upon the authority of the charter granted to it by the Congress in 1863, the Academy has a mandate that requires it to advise the federal government on scientific and technical matters. Dr. Ralph J. Cicerone is president of the National Academy of Sciences.
The National Academy of Engineering was established in 1964, under the charter of the National Academy of Sciences, as a parallel organization of outstanding engineers. It is autonomous in its administration and in the selection of its members, sharing with the National Academy of Sciences the responsibility for advising the federal government. The National Academy of Engineering also sponsors engineering programs aimed at meeting national needs, encourages education and research, and recognizes the superior achievements of engineers. Dr. Charles M. Vest is president of the National Academy of Engineering.
The Institute of Medicine was established in 1970 by the National Academy of Sciences to secure the services of eminent members of appropriate professions in the examination of policy matters pertaining to the health of the public. The Institute acts under the responsibility given to the National Academy of Sciences by its congressional charter to be an adviser to the federal government and, upon its own initiative, to identify issues of medical care, research, and education. Dr. Harvey V. Fineberg is president of the Institute of Medicine.
The National Research Council was organized by the National Academy of Sciences in 1916 to associate the broad community of science and technology with the Academy's purposes of furthering knowledge and advising the federal government. Functioning in accordance with general policies determined by the Academy, the Council has become the principal operating agency of both the National Academy of Sciences and the National Academy of Engineering in providing services to the government, the public, and the scientific and engineering communities. The Council is administered jointly by both Academies and the Institute of Medicine. Dr. Ralph J. Cicerone and Dr. Charles M. Vest are chair and vice chair, respectively, of the National Research Council.
www.national-academies.org
Page iv Share Cite
This page intentionally left blank.
Page v Share Cite
COMMITTEE ON THE REVIEW OF THE WATER AND ENVIRONMENTAL RESEARCH SYSTEMS (WATERS) NETWORK
GEORGE M. HORNBERGER, Chair,
Vanderbilt University, Nashville, Tennessee
MARY JO BAEDECKER,
U.S. Geological Survey, Scientist Emeritus, Reston, Virginia
YU-PING CHIN,
Ohio State University, Columbus
GLEN T. DAIGGER,
CH2M Hill, Englewood, Colorado
TONY R. FOUNTAIN,
TIMOTHY K. KRATZ,
University of Wisconsin, Boulder Junction
RICHARD G. LAWFORD,
Global Energy and Water Cycle Experiment, Winnipeg, Manitoba, Canada
DANIEL P. LOUCKS,
Cornell University, Ithaca, New York
CHARLES R. O'MELIA,
Johns Hopkins University, Baltimore, Maryland
STEPHEN POLASKY,
University of Minnesota, St. Paul
NANCY N. RABALAIS,
Louisiana Universities Marine Consortium, Chauvin
JOHN T. SCHOLZ,
Florida State University, Tallahassee
THOMAS C. WINTER,
U.S. Geological Survey, Denver, Colorado
NRC Staff
STEPHANIE E. JOHNSON, Study Director
MICHAEL J. STOEVER, Research Associate
Page vi Share Cite
CLAIRE WELTY, Chair,
OTTO C. DOERING,
Purdue University, West Lafayette, Indiana
JOAN G. EHRENFELD,
Rutgers University, New Brunswick, New Jersey
GERALD E. GALLOWAY,
CHARLES N. HAAS,
Drexel University, Philadelphia, Pennsylvania
KENNETH R. HERD,
Southwest Florida Water Management District, Brooksville
JAMES M. HUGHES,
Emory University, Atlanta, Georgia
KIMBERLY L. JONES,
Howard University, Washington, DC
MICHAEL J. MCGUIRE,
Michael J. McGuire, Inc., Los Angeles, California
G. TRACY MEHAN,
The Cadmus Group, Inc., Arlington, Virginia
DAVID H. MOREAU,
DENNIS D. MURPHY,
THOMAS D. O'ROURKE,
DONALD I. SIEGEL,
Syracuse University, New York
SOROOSH SOROOSHIAN,
STEPHEN D. PARKER, Director
JEFFREY W. JACOBS, Scholar
LAURA J. EHLERS, Senior Program Officer
STEPHANIE E. JOHNSON, Senior Program Officer
LAURA E. HELSABECK, Program Officer
M. JEANNE AQUILINO, Financial and Administrative Associate
ELLEN A. DE GUZMAN, Senior Program Associate
ANITA A. HALL, Senior Program Associate
STEPHEN T. RUSSELL, Senior Program Assistant
Page vii Share Cite
For nearly a decade, a substantial group from the hydrologic sciences community has been engaged in discussions about formation of a network of hydrologic observatories. This coincided with a time when the National Science Foundation (NSF) was considering how to achieve the goals of "big-science" through environmental observing systems. With encouragement from NSF to proceed with plans for a network of hydrologic observatories, the WATERS initiative was born in 2005. This committee reviewed the Draft Science, Education, and Design Strategy (SEDS) document in 2008 and criticized the absence of a clear scientific vision for the project. Between August 2008 and May 2009, a team of scientists and engineers, led by Professor Jeff Dozier, prepared a Science Plan presenting the vision for an observatory network. It was the privilege of the committee who prepared this report to review this WATERS Science Plan.
The committee brought to its task a breadth of knowledge gained from experience with field research as well as from related scientific literature and reports produced during the planning of hydrologic observatories. The WATERS Science Plan was read and reviewed within this broad contextual background. The committee benefited greatly from frank and open briefings provided by members of the WATERS team and by NSF leaders from three directorates, briefings that led to much greater appreciation of both the great potential for an observatory network and also some of the challenges associated with it.
As chair of the committee, I thank the members of the committee for their hard work in preparing three reports, of which this is the final one, and for the way that everyone interacted with great good nature throughout our work together. This report, like all National Research Council (NRC) reports, was made possible by excellent staff work. My thanks to Michael Stoever for managing logistics for the committee and to Dorothy
Page viii Share Cite
Weir, who very ably served as study director for the committee for the first year and a half. I especially want to thank Stephanie Johnson for her major contributions to our work. Stephanie served as the study director for the interim and final reports. Special thanks are due for both editorial and substantive suggestions she made on the reports and for shepherding the reports through the NRC publication process.
This report has been reviewed in draft form by individuals chosen for their diverse perspectives and technical expertise, in accordance with the procedures approved by the NRC's Report Review Committee. The purpose of this independent review is to provide candid and critical comments to assist the institution in making its published report as sound as possible and to ensure that the report meets institutional standards for objectivity, evidence, and responsiveness to the study charge. The review comments and draft manuscript remain confidential to protect the integrity of the deliberative process. We wish to thank the following individuals for their review of this report:
A. ALLEN BRADLEY, University of Iowa
JAMES R. GOSZ, University of Idaho
WENDY D. GRAHAM, University of Florida
SALLY MACINTYRE, University of California, Santa Barbara
DAVID L. SEDLAK, University of California, Berkeley
EDELLA C. SCHLAGER, University of Arizona
Although the reviewers listed above have provided many constructive comments and suggestions, they were not asked to endorse the conclusions and recommendations nor did they see the final draft of the report before its release. The review of this report was overseen by Mary Anderson, University of Wisconsin. Appointed by the NRC, she was responsible for making certain that an independent examination of this report was carried out in accordance with institutional procedures and that all review comments were carefully considered. Responsibility for the final content of this report rests entirely with the authoring committee and the institution.
George Hornberger, Chair
Page ix Share Cite
Study Scope and Purpose of This Report,
EVALUATION OF THE WATERS NETWORK SCIENCE PLAN
Overarching Science Question,
The Three Grand Challenges,
Prototype Network,
Additional Benefits of the WATERS Network,
Future Challenges: Cyberinfrastructure,
Conclusions and Recommendations,
OBSERVATIONAL NETWORKS
The Network Idea,
Evaluation of the WATERS Network Science Plan Against Criteria for Networks,
MAJOR RESEARCH EQUIPMENT AND FACILITIES CONSTRUCTION
Defining a Facility Under MREFC,
Case for Establishing the WATERS Network with MREFC Funding,
INTEGRATION AND COORDINATION WITH EXISTING NETWORKS
Page x Share Cite
State and Local Agencies,
A Letter Report Reviewing the WATERS Network Science Plan
B Committee and Staff Biographical Sketches
Next: Summary »
Review of the WATERS Network Science Plan Get This Book
Buy Paperback | $29.00 Buy Ebook | $23.99
One of the most critical issues facing the United States today is the proper management of our water resources. Water availability and quality are changing due to increasing population, urbanization, and land use and climate change, and shortages in water supply have been increasing in frequency in many parts of the country. The National Science Foundation (NSF) has entertained the Water and Environmental Research Systems (WATERS) Network as one possible initiative whereby NSF could provide the advances in the basic science needed to respond effectively to the challenge of managing water resources.
The WATERS Network, a joint initiative of the Engineering, the Geosciences, and the Social, Behavioral and Economic Sciences directorates at NSF, is envisioned as an integrated national network of observatories and experimental facilities supporting research, outreach, and education on large-scale, water-related environmental problems. The proposed observatories would provide researchers with access to linked sensing networks, data repositories, and computational tools connected through high-performance computing and telecommunications networks.
This book, the final of a series about the WATERS project, provides a more detailed review of the Science Plan and provides advice on collaborating with other federal agencies.
Front Matter i–x
Summary 1–5
1 Introduction 6–11
2 Evaluation of the WATERS Network Science Plan 12–27
3 Observational Networks 28–37
4 Major Research Equipment and Facilities Construction 38–43
5 Integration and Coordination with Existing Networks 44–54
References 55–56
Appendix A: Letter Report Reviewing the WATERS Network Science Plan 57–62
Appendix B: Committee and Staff Biographical Sketches 63–70


Published 04/20/2019 02:10:24 pm at 04/20/2019 02:10:24 pm in Spa Light Cover.
spa light cover pool light cover matching universal to other existing pool and spa lights poolside blog swimming pool amazoncom pentair housing spacer replacement aqualumin pentair mounting spacer replacement aqualumin pool and spa light.
amazoncom pentair kwikchange plastic snapon color lens pentair kwikchange plastic snapon color lens cover replacement kit amerlite underwater, at skycar picture of durban spa durban tripadvisor durban spa light cover, amazoncom womens waffle bath wrap female spa body wrap light eluxury womens waffle bath wrap female spa body wrap light cover up waffle shower wrap , pentair medium blue tempered lens cover and face ring american products pool spa amerlite amerquatrz light lens blue , hollywood light fixture cover light cover related post vanity light hollywood light fixture cover light cover bathroom spa lighting design mirror with vanity lights bar update hollywood light fixture cover , pool light lens cover joejunecom pool light lens cover change amber green red blue pool spa light lens set swimming pool, amazoncom pentair magenta kwik change color lens cover pentair magenta kwik change color lens cover replacement spabrite and aqualight poolspa light, amazoncom pentair red kwikchange plastic snapon color pentair red kwikchange plastic snapon color lens cover replacement spabrite,, amazoncom red blue lens cover for spa hot tub light lens red blue lens cover for spa hot tub light lens quot, pentair amerlite v w underwater swimming pool light w pentair intellibrite swimming pool spa light cover .


Do opt to visit the largest province in Spain with cheap flights to Badajoz. Being a centre to financial and commercial activity, this city offers historic monuments that illustrate Spain's rich history, such as the Cathedral Museum and the Museum of Badajoz. These structures stand tall, attracting attention for tourists to get an insight into their history and architectural art. The City Hall, which is adjacent to the cathedral, has an intimidating façade resting on Tuscan columns built during the 18th century. The locals are generally found to be warm and welcoming, extending their services wherever possible to help out foreigners. Badajoz offers excellent quality meat along with fresh vegetables and fruits, all accompanied by local vineyards and hotels, making it a treat to visit and eat-out. Air Europa counts among low-cost airlines with TravelhouseUK.


text:
Water line break at Silverthorne Elementary School
Emergency water shut off on Thirteenth Street from Butler Avenue to Copeland Avenue
Ann Marie Hak
On Nov. 21, 2017 a water line break was discovered at Silverthorne Elementary School resulting in an emergency water shut off for homes and apartments located on Thirteenth Street between Butler Avenue and Copeland Avenue.
According to the District of Houston Facebook page, staff are investing the break and have notified affected residents.
At the District of Houston council meeting on Nov. 21, 2017 council asked for an update on the investigation.
Michael Glavin, Chief Administrative Officer for the District of Houston, said, "We have a water leak in the crawl space of Silverthorne [Elementary School], we do believe it is on their side, however, we are unable to find our cut off valve."
Glavin added that it was discovered that the pipe that has the leak is a lead pipe.
District staff went house to house to inform the homes and called the landlords of apartments to inform them about the situation.
Counsellor Dennis Tait asked, "How many places have been affected?"
"Around 15 homes plus apartments," said Glavin.
Glavin added that the water will continue to be shut off for 24 hours.
On Nov. 22, 2017 around 4:30 p.m. Houston residents on Thirteenth Street had water again.
One-in-five 911 calls are 'non-emergencies': E-Comm
Syringe found in downtown Victoria parking dispenser


What do I want to come in 2013? What I want is simple: more chaos.
I have no interest in trying to replicate our old print models or owning e-books. I'm enough of a librarian to want someone out there to maintain a permanent copy—but please don't make it be me. My collection is dynamic and ever changing. There are few titles I want to access after three years, fewer still after eight. I want business models that will support this fluidity. I actually like the model created by HarperCollins—once reviled, now our BFF—but I would welcome different models. I'll entertain paying per use or licensing for a year—or five years.


text:
Amazon looks to use Chile's cutting-edge telescopes to datamine the stars
September 13, 2018 - 7:09 am
Frances Jenner
E-commerce giant Amazon is in talks with the Chilean government to house and mine huge quantities of star data generated by the country's state-of-the-art telescopes.
Reuters reported that the potential agreement could have benefits for both parties. Chilean President Sebastián Piñera is looking to reduce Chile's economy on copper mining, of which it is the largest producer in the world.
He announced last week that the country plans to pool data from its telescopes onto a virtual observatory stored in the digital cloud, although he did not specify a timeframe for this ambitious project.
Currently, 70 percent of money pumped into astronomy globally ends up in Chile's observatories due to the ideal conditions provided by its Atacama desert.
The cloudless skies, lack of rain and limited light pollution create perfect stargazing conditions for more that 300 nights a year, and has recently given us the sharpest picture yet of Neptune. However, storing all the astrodata from their observatories, which contains information about over a billion stars, constitutes a great IT burden on any observatory.
A new optical system installed on the @ESO Very Large Telescope in the Atacama Desert in Chile has come into service, producing images as sharp, according to its operators, as those produced by the @NASAHubble Space Telescope #Space #Astrophotography
►https://t.co/kPTHZGkvuq pic.twitter.com/fU6NbM2Cqy
— GinGo (@GinGoResearch) July 25, 2018
An official at InvestChile told Reuters that Amazon and the Chilean government had been in talks to discuss the potential of Amazon Web Services (AWS) storing this immense data on the cloud. Jeffrey Kratz, AWS' general manager for Latin America, the Caribbean and Canada, told Reuters that the group is very interested in AWS' prospects in Chile.
"Chile is a very important country for AWS," he said in an email to Reuters. "We kept being amazed about the incredible work on astronomy and the telescopes, as real proof points on innovation and technology working together," adding that "The Chilean telescopes can benefit from the cloud by eliminating the heavy lifting of managing IT."
However, science outlet Futurism explained that this is not coming purely from Amazon CEO Jeff Bezos' love of space. Amazon has historically had difficulties gaining traction in Latin America, and the use of AWS in Chile would be a significant step in his desire to expand the company into the region.
Not only this, but the information gathered from the astrodata mining has the potential to develop AI tools that could be used for other purposes.
Julio Pertuze, a ministry official from the Chilean government told Reuters that these tools could develop projects to track shoplifters, potential fare-evaders and even endangered animals. Astronomer Chris Smith added that this technology could also be used in diverse areas such as medicine and banking in order to spot anomalies in large data sets.
Bezos already has his fingers in other astronomical pies, as Amazon provides a cloud platform to store data for the Hubble telescope and the International Centre for Radio Astronomy Research in Australia.
However, his rival Google isn't far behind and has already stepped foot on the Atacama desert. Google is a member of Chile's Large Synoptic Survey Telescope (LSST), which will become operational in 2022, and a Google spokesperson said the company would announce expansion plans for their Chilean data centre on Sept. 12.
Although talks have been taking place between Amazon and the Chilean government for over two years, no decision has been made and no contract has been signed.
There is no time to dally, however, as a new telescope called the Giant Magellan Telescope (GMT) began construction in Chile in August and its cutting edge technology hopes to collect light from the earliest days of the universe.
With Chile stepping into its astronomical powerhouse shoes, both Google and Amazon will be attempting to mine its astrodata in order to develop powerful AI tools that could have benefits for for the human race as a whole.
This article was originally published on Chile Herald by Frances Jenner, you can read the original article here.
Published September 13, 2018 - 7:09 am UTC
Jeff Bezos' Blue Origin unveils plans to occupy space
Amazon puts its own "brands" first above better-rated products
Startup harnesses self-supervised learning to tackle speech recognition biases
Sorry former Pentagon expert, but China is nowhere near winning the AI race


It's Black Friday and the start of the busy holiday buying season.
We've procured some fun, educational gift ideas we think your STEM-loving kids will enjoy.
An exciting gift for the super hero in your life! This is a fun kit for kids who love to build with LEGOS, K'NEX, and littlebits. With 18 different different activities, children build, code, and customize their creations.
This is not your average playing with marbles set! In this fun marble run, children build their own marble tracks while they experiment with physics, magnetism, and kinetics.
Star Wars fans … Sphero Droid Robots … how lucky are your kids to own their very own R2D2! Bluetooth enabled, connect to iphone/android smart phone or tablet.
Are your kids looking for more challenge? If they've figured out how to solve the Rubik's Cube, have them try their hand on the next level in Rubik's-esq puzzles.
Not ready to get a dog for your child? How about building one that can sing? These 3D laser cut wooden puzzles are fun to build and even more entertaining to hear! There's different models to include robots, submarines, trains .. just to name a few.
If you have kids who are hankering to build their own computer, this is a great first step. It's an actual working computer which uses Raspberry Pi 3 software. You'll need a monitor to plug the computer into. The company also offers build a laptop, tablet, and build you own computer screen (which you can use with the computer kit for a complete system).
This handy chess set is ideal for children starting their chess tournament journey (chess team parents … this is for you!).
The bag is a strong canvas and inside are pockets to hold your chess accessories. This initial kit comes with a weighted chess set (heavier chess pieces) and board.
Chess clocks and notation books are not included, see below for our recommendations.
By the way, we like bags that don't have advertising embroidered on the outside (as some other versions have).
This is the chess clock we use at the Academy, it's small and sturdy enough to use with children.
All rated tournaments use chess clocks and it's easier if kids can use their own.
As your children build into becoming a serious competitive chess player, it's nice to have a sturdier chess scorebook, especially ones with a hardcover.
Families who are not interested in the tournament set but still want a portable chess set at home, this fits the bill. The handy bag has a slot to hold the board and handles for easy carrying.
These are Amazon affiliate links. We receive a small commission if items are purchased but you DO NOT pay more for them.


text:
Spielberger State-Trait Anxiety Inventory (STAI)
The STAI includes 40 items on a 4 point scale. This questionnaire includes 20 items for assessing trait anxiety and 20 for state anxiety. State anxiety items include: "I am tense; I am worried" and "I feel calm; I feel secure." Trait anxiety items include: "I worry too much over something that really doesn't matter" and "I am content; I am a steady person." All items are rated on a 4-point scale (e.g., from "Almost Never" to "Almost Always"). It can be used in clinical settings to diagnose anxiety and to distinguish it from depressive syndromes. It also is often used in research as an indicator of caregiver distress
Year: 1983 Authors: Spielberger et al Disease: COPD Outcome: Coping with the disease, including depression and anxiety
See more tools that use this outcome Measure: Anxiety
See the RCTs Scale: Lower scores are better Reference: Spielberger, C. D., Gorsuch, R. L., Lushene, R., Vagg, P. R., & Jacobs, G. A. (1983). Manual for the State-Trait Anxiety Inventory. Palo Alto, CA: Consulting Psychologists Press.
Target population: General population Focus Generic Translations available: Yes Original version validated: Yes Original language: English Form of delivery: Self-reported Licence needed: Yes
Blumenthal, J. A. The effects of a telehealth coping skills intervention on outcomes in chronic obstructive pulmonary disease: primary results from the INSPIRE-II study
Bauldoff, Gerene S. Exercise Maintenance Following Pulmonary Rehabilitation
Donesky-Cuenco, D. Yoga therapy decreases dyspnea-related distress and improves functional performance in people with chronic obstructive pulmonary disease: a pilot study
Jiang, X. Effects of an uncertainty management intervention on uncertainty, anxiety, depression, and quality of life of chronic obstructive pulmonary disease outpatients


text:
Mini golf through Bay Area landmarks
Arts & Entertainment // Entertainment
LEISURE Alameda mini-golf course dotted with Bay Area landmarks
Peter Hartlaub Nov. 21, 2012 Updated: Nov. 21, 2012 2:51 p.m.
1of5Jerisha Green and Tyrone Knox enjoy a round at Subpar in Alameda, where the holes are re-creations of Bay Area landmarks.Photo: Lance Iversen, The Chronicle
2of5Golfers play one of the holes at a one-of-a-kind miniature golf course recently opened in Alameda. Subpar has holes that were made by a local high school shop teacher, and the owner of Subpar Miniature Golf Course on Park Street. Saturday Nov. 17, 2012.Photo: Lance Iversen, The Chronicle
3of5Owner Michael Taft says he nearly abandoned the project three times.Photo: Peter Hartlaub, The Chronicle
4of5A miniature freeway interchange presents challenges to golfers at the Alameda mini-course, where Bay Area landmarks mark the holes.Photo: Lance Iversen, The Chronicle
5of5Left: Kids peer inside a replica of the Winchester Mystery House at Subpar.Photo: Lance Iversen, The Chronicle
The MacArthur Maze has been busy all afternoon, which is a good thing in Michael Taft's world.
The proprietor and mastermind behind Subpar in Alameda wasn't sure if people would show up to an indoor miniature golf course, with Bay Area landmark-themed holes.
"A long time ago, I decided that I might open a miniature golf course as a retirement plan, way down the line," Taft says. "'Research led me to find there weren't any miniature golf places in Oakland, San Francisco, Berkeley, Alameda ... we're even the closest miniature golf course to Richmond."
It's safe to say there's nothing like Subpar anywhere, locally or beyond. Instead of a hiring a firm that specializes in theme parks, the Oakland resident deputized a group of his talented artist friends. He went into debt, and almost shut the project down three times before opening day. When the course premiered on main drag Park Street in August, it was part family entertainment center, part art installation and all Bay Area.
On the first hole, the ball navigates Altamont Pass windmill blades, passes through a mountain and falls into a valley of lush Astroturf. (Would that be Dublin?) Along with other obvious landmarks - the Golden Gate Bridge is a double loop-de-loop - there are more obscure sights to test your Bay Area cred.
Balls travel along the MacArthur Maze freeway interchange, and there's a hole paying tribute to a Berkeley skate park. Yes, that's a Fruitvale taco truck theme on the third hole. And in a nod to Alameda residents, the Park Street drawbridge is at the 17th hole, with the bridge open halfway for added difficulty.
"Live out your fantasy of jumping the Park Street Bridge," Taft says. "This way is much safer."
Taft, 29, grew up on the East Coast, where he says miniature golf courses are more plentiful. The industrial designer says the idea for Subpar came while discussing open studio art gallery events at F3 at the Cotton Mill. Artists suggested creating a miniature golf hole in each gallery, to generate interest and get people circulating.
There were logistical problems with that, but Taft started to see miniature golf as a commercial business opportunity. He found a good piece of property on Park Street - a former Video Maniacs store, mostly abandoned for three years - and started calling some of the artists and craftspeople he knew.
'Strange things'
"I know a lot of weirdos, is what I like to say," he says. "I have friends and neighbors and acquaintances who like to do interesting and strange things."
Taft's roommate Jacob Cohen designed the course. Next-door neighbor Martin Sweet, a former shop teacher at Alameda High School, was a project manager. Many of the contributors have local ties. Caren Corley was on the build team, and now works as an assistant manager. Zach Wong drew an impressive mural of the Bay Area which wraps around the J-shaped golf course space.
"There were so many talented people involved," said Wong, a 22-year-old Alameda High graduate. "The hardest part for me was wondering if what I bring to the table would be good enough."
Taft, who has a little bit of a "Big Lebowski" vibe, is the first to admit he was a little too laid back in the beginning. The ceiling leaked, the electricity wasn't up to code and the back wall was termite-ridden. The project was six months late opening in June, due mostly to unforeseen construction costs.
Artists at work
The delays led to more curiosity for residents of the bedroom community. The crew eventually opened the doors on summer days and let people in to see the progress and watch artists work.
Nicola Taggart dropped in for the first time with husband Bill Taggart and two children, 12-year-old Ella and 7-year-old Lindsay.
"I can't believe they got 18 holes in here," she said. "It's fun. The Lombard Street one was cool. I also liked the one with the freeway."
Taft likes the freeway, too. But most of his focus is on what still needs to be done. Starting a one-of-a-kind miniature golf course leads to one-of-a-kind problems. The crew had to close on election day to bore a second hole in the Altamont Pass, because the ball kept getting stuck in the first one. The Winchester Mystery House was a little too mysterious - balls were disappearing.
Taft says the children's party room - a former adult video nook - needs to look a little cheerier. His dream of adding electroluminescent wire to the landmarks for after-hours events is on hold until more capital comes in.
But that's part of the fun.
"I don't think I'm ever going to look at this place and say 'It's completely done.' But every day it gets a little bit better," Taft says. "We don't want to ever lose the homemade feel that we've got here. It's not polished, but we're kind of OK with that."
Taft lost sleep, got depressed, and came very close to quitting. But the greatest Bay Area landmarks involved sacrifice before reward. And Taft is seeing that part of it too.
"After all is said and done, we did get open, and I get to see a lot of people leave here with smiling faces," Taft says. "Every once in a while, you'll hear a giant cheer in the back by a group that sunk a (great) putt. It makes me feel really good, like 'We did that. That's us.' "
Subpar Miniature Golf is open seven days a week (including Thanksgiving).1511 Park St., Alameda. $9 for adults and $7 for children 2-12, students and seniors 55 and older. (510) 521-4653 or www.subparminigolf.com.
Peter Hartlaub is The San Francisco Chronicle's pop culture critic. E-mail: phartlaub@sf chronicle.com Twitter: @PeterHartlaub
Peter Hartlaub
Follow Peter on:
https://www.facebook.com/SFChronicle/peterhartlaub
Peter Hartlaub is The San Francisco Chronicle's pop culture critic and host of the podcast The Big Event. The Bay Area native has worked at The Chronicle since 2000, and was a Chronicle paperboy from 1982 to 1984. He reviews movies, television and comedy, covers entertainment, creates multimedia projects and writes the Our San Francisco local history column. The Big Event is recorded in The Chronicle's basement archive. Hartlaub lives in Alameda.
'Crawl,' and seven more good movies that didn't screen for critics
Apollo 11 advertisements: First Mad Men on the moon
Dan the Automator follows his own lane to food, movies, 'Always Be My Maybe'
How to 'eat' makeup: An ASMR artist reveals her tricks
Harjo first Native American to be named U.S. Poet Laureate
Having located the Exit sign, I am proceeding to the exit
And (almost finally), some of the things I hate


text:
You are here: Home / Celebrities / Kevin Spacey's Sexual Misconduct Allegations
Kevin Spacey's Sexual Misconduct Allegations
The House of Cards star Kevin Spacey has gone quiet after sexual misconduct allegation emerged from numerous sources.
The allegations started when the actor Anthony Rapp claimed that Spacey had acted inappropriately towards him when he was 14 years old. After these allegations emerged, others have spoken out that the 58-year-old star has acted inappropriately towards them.
Spacey's lawyers have said that the star denies all allegations.
However, sources say that the star has remained quiet, because he is guilty and because he knows that he will not be able to get good work in the future.
Kevin Spacey's film "All the money in the world," will not be part of the AFI fest TriStar Pictures announced. TriStar Pictures said that although the film was an excellent film, they will not celebrate the film at the AFI fest because of the actor's allegations and out of respect of those impacted. The film, however, will be in cinemas on December 22nd as the company believes that the film is not the work of one person.
After this news, the House of Cards' production company, Media Rights Capital, announced that Spacey would be suspended from the series. Netflix who broadcasts the show added that they would not be involved in the further production of House of Cards if it includes Kevin Spacey.
Spacey's representative said that the actor is now taking time off acting and looking at evaluation and treatment.
How Tia Mowry lost 20 Lbs June 5, 2017 By admin
Scott Disick Says That Dating Kourtney Was Not Fulfilling November 6, 2017 By admin
Janet Jackson prepares to tour as a single mom
Jessica Szohr on 'Gossip Girl' co-star and ex Ed Westwick's rape allegations


Download Unatumika Broo by Kelechi Africana Ft Latinoh Onfleek.
Kelechi Africana Ft Latinoh Onfleek – Unatumika Broo [Mp3 Download].
Its a brand new hit track from the 'Fleek Madeit' CEO Kelechi Africana featuring Latinoh Onfleek dubbed 'Unatumika Broo'.
After ditching Kubwa Studios Lechi decided to go solo under his own management.


text:
Piotr Kozłowski (ur. 10 stycznia 1955 w Puszczykowie) – polski leśnik, poseł na Sejm II kadencji, długoletni przewodniczący Związku Leśników Polskich Parków Narodowych.

Życiorys
Uzyskał wykształcenie wyższe w zakresie ochrony przyrody i zasobów leśnych. Podjął pracę w Wielkopolskim Parku Narodowym. W 1992 zainicjował powołanie Związku Leśników Polskich Parków Narodowych. Przez 25 lat pełnił funkcję przewodniczącego tej organizacji. Był też wiceprzewodniczącym Związku Leśników Polskich w Rzeczypospolitej Polskiej.

W latach 1993–1997 był posłem II kadencji wybranym w okręgu Poznań jako bezpartyjny kandydat z listy Polskiego Stronnictwa Ludowego. W 1997 nie uzyskał ponownie mandatu. W 2006 z ramienia PSL bezskutecznie ubiegał się o mandat radnego powiatu poznańskiego.

Odznaczenia i wyróżnienia
W 2012, za wybitne zasługi w działalności na rzecz rozwoju leśnictwa i ochrony środowiska naturalnego, za działalność związkową, został odznaczony Krzyżem Kawalerskim Orderu Odrodzenia Polski. Wyróżniony też m.in. Złotym Znakiem Związku Leśników Polskich w RP.

Przypisy

Bibliografia

Ludzie urodzeni w Puszczykowie
Odznaczeni Krzyżem Kawalerskim Orderu Odrodzenia Polski (III Rzeczpospolita)
Politycy Polskiego Stronnictwa Ludowego
Polscy związkowcy
Posłowie na Sejm III Rzeczypospolitej
Urodzeni w 1955

redpajama_set_name: RedPajamaWikipedia


December UK release date for Nintendo 3DS?
The Nintendo 3DS is not likely to arrive in the UK until December, with the company's hopes of an October release ahead of Christmas likely to be confounded.
According to CVG, who have spoken to a senior games retail source, plans for an October launch are now being abandoned, with a limited amount of stock now set to appear in December.
That leaves precious little time for those hoping to upgrade to the latest handheld for Christmas will face a battle for units and a race against time.
"Early indications to us are that the launch is going to emulate Wii in December," the source told CVG.
"We've been informed that Nintendo wanted a long run-up to Christmas, but now it's going to be a close-run thing.
"We're not expecting a lot of stock before next year."
As you may imagine, Nintendo has insisted that all talk of a release date is still speculative.


text:
package org.infinispan.protostream.annotations.impl.processor.types;

import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import javax.annotation.processing.ProcessingEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

import org.infinispan.protostream.annotations.impl.processor.AutoProtoSchemaBuilderAnnotationProcessor;
import org.infinispan.protostream.annotations.impl.types.DocumentationExtractor;
import org.infinispan.protostream.annotations.impl.types.ReflectionTypeFactory;
import org.infinispan.protostream.annotations.impl.types.XClass;
import org.infinispan.protostream.annotations.impl.types.XConstructor;
import org.infinispan.protostream.annotations.impl.types.XEnumConstant;
import org.infinispan.protostream.annotations.impl.types.XField;
import org.infinispan.protostream.annotations.impl.types.XMethod;
import org.infinispan.protostream.annotations.impl.types.XTypeFactory;

/**
 * Implementation relying primarily on {@link javax.lang.model.type.TypeMirror}, but also capable to use reflection
 * similarly to {@link ReflectionTypeFactory}.
 *
 * @author anistor@redhat.com
 * @since 4.3
 */
public final class MirrorTypeFactory implements XTypeFactory {

   private static final XClass[] EMPTY_XCLASS_ARRAY = new XClass[0];

   private final Elements elements;

   private final Types types;

   private final Map<String, XClass> classCache = new HashMap<>();

   private final MirrorPrimitiveType voidType;

   private final MirrorPrimitiveType booleanType;

   private final MirrorPrimitiveType byteType;

   private final MirrorPrimitiveType shortType;

   private final MirrorPrimitiveType intType;

   private final MirrorPrimitiveType longType;

   private final MirrorPrimitiveType charType;

   private final MirrorPrimitiveType floatType;

   private final MirrorPrimitiveType doubleType;

   private final boolean fullyQualifiedAnnotations;

   public MirrorTypeFactory(ProcessingEnvironment processingEnv) {
      elements = processingEnv.getElementUtils();
      types = processingEnv.getTypeUtils();
      fullyQualifiedAnnotations = Boolean.parseBoolean(processingEnv.getOptions().get(AutoProtoSchemaBuilderAnnotationProcessor.FULLY_QUALIFIED_ANNOTATIONS));
      voidType = new MirrorPrimitiveType(void.class, types.getNoType(TypeKind.VOID));
      booleanType = new MirrorPrimitiveType(boolean.class, types.getPrimitiveType(TypeKind.BOOLEAN));
      byteType = new MirrorPrimitiveType(byte.class, types.getPrimitiveType(TypeKind.BYTE));
      shortType = new MirrorPrimitiveType(short.class, types.getPrimitiveType(TypeKind.SHORT));
      intType = new MirrorPrimitiveType(int.class, types.getPrimitiveType(TypeKind.INT));
      longType = new MirrorPrimitiveType(long.class, types.getPrimitiveType(TypeKind.LONG));
      charType = new MirrorPrimitiveType(char.class, types.getPrimitiveType(TypeKind.CHAR));
      floatType = new MirrorPrimitiveType(float.class, types.getPrimitiveType(TypeKind.FLOAT));
      doubleType = new MirrorPrimitiveType(double.class, types.getPrimitiveType(TypeKind.DOUBLE));
   }

   @Override
   public XClass fromClass(Class<?> c) {
      if (c == null) {
         return null;
      }

      if (c == byte[].class) {
         XClass componentType = byteType;
         String fqn = "[" + componentType.getName();
         XClass xclass = classCache.get(fqn);
         if (xclass == null) {
            xclass = new MirrorArray(componentType);
            classCache.put(fqn, xclass);
         }
         return xclass;
      }
      if (c == void.class) {
         return voidType;
      }
      if (c == boolean.class) {
         return booleanType;
      }
      if (c == byte.class) {
         return byteType;
      }
      if (c == short.class) {
         return shortType;
      }
      if (c == int.class) {
         return intType;
      }
      if (c == long.class) {
         return longType;
      }
      if (c == char.class) {
         return charType;
      }
      if (c == float.class) {
         return floatType;
      }
      if (c == double.class) {
         return doubleType;
      }

      String typeName = c.getCanonicalName();
      if (typeName == null) {
         typeName = c.getName();
      }
      TypeElement typeElement = elements.getTypeElement(typeName);
      if (typeElement == null) {
         // this should never happen because once we have a java.lang.Class instance we should always be able to obtain its TypeElement
         throw new IllegalStateException("Type not found : " + typeName);
      }
      return fromTypeMirror(typeElement.asType());
   }

   /**
    * Wraps the given TypeMirror in an XClass. Implementation must be idempotent. The returned value must be
    * reference-identical.
    *
    * @param typeMirror can be null
    * @return the wrapper XClass, or null iff the actual argument is null
    */
   public XClass fromTypeMirror(TypeMirror typeMirror) {
      if (typeMirror == null) {
         return null;
      }

      switch (typeMirror.getKind()) {
         case ERROR:
            throw new IllegalStateException("Unresolved type : " + typeMirror.toString());
         case VOID:
            return voidType;
         case BOOLEAN:
            return booleanType;
         case BYTE:
            return byteType;
         case SHORT:
            return shortType;
         case INT:
            return intType;
         case LONG:
            return longType;
         case CHAR:
            return charType;
         case FLOAT:
            return floatType;
         case DOUBLE:
            return doubleType;
         case DECLARED: {
            DeclaredType declaredType = (DeclaredType) typeMirror;
            String fqn = ((TypeElement) declaredType.asElement()).getQualifiedName().toString();
            XClass xclass = classCache.get(fqn);
            if (xclass == null) {
               xclass = new MirrorClass(declaredType);
               classCache.put(fqn, xclass);
            }
            return xclass;
         }
         case ARRAY: {
            XClass componentType = fromTypeMirror(((ArrayType) typeMirror).getComponentType());
            String fqn = "[" + componentType.getName();
            XClass xclass = classCache.get(fqn);
            if (xclass == null) {
               xclass = new MirrorArray(componentType);
               classCache.put(fqn, xclass);
            }
            return xclass;
         }
         default:
            throw new IllegalStateException("Unexpected type kind : " + typeMirror.getKind());
      }
   }

   /**
    * Translate the given element modifiers from javax.lang.model.element.Modifier to java.lang.reflect.Modifier.
    */
   private static int getModifiersOfElement(Element element) {
      int modifiers = 0;
      for (Modifier mod : element.getModifiers()) {
         switch (mod) {
            case DEFAULT:
               // lost in translation
               break;
            case PUBLIC:
               modifiers |= java.lang.reflect.Modifier.PUBLIC;
               break;
            case PROTECTED:
               modifiers |= java.lang.reflect.Modifier.PROTECTED;
               break;
            case PRIVATE:
               modifiers |= java.lang.reflect.Modifier.PRIVATE;
               break;
            case ABSTRACT:
               modifiers |= java.lang.reflect.Modifier.ABSTRACT;
               break;
            case STATIC:
               modifiers |= java.lang.reflect.Modifier.STATIC;
               break;
            case FINAL:
               modifiers |= java.lang.reflect.Modifier.FINAL;
               break;
            case TRANSIENT:
               modifiers |= java.lang.reflect.Modifier.TRANSIENT;
               break;
            case VOLATILE:
               modifiers |= java.lang.reflect.Modifier.VOLATILE;
               break;
            case SYNCHRONIZED:
               modifiers |= java.lang.reflect.Modifier.SYNCHRONIZED;
               break;
            case NATIVE:
               modifiers |= java.lang.reflect.Modifier.NATIVE;
               break;
            case STRICTFP:
               modifiers |= java.lang.reflect.Modifier.STRICT;
               break;
         }
      }
      return modifiers;
   }

   private TypeMirror getTypeMirror(String typeName) {
      if ("void".equals(typeName)) {
         return types.getNoType(TypeKind.VOID);
      }
      if ("boolean".equals(typeName)) {
         return types.getPrimitiveType(TypeKind.BOOLEAN);
      }
      if ("char".equals(typeName)) {
         return types.getPrimitiveType(TypeKind.CHAR);
      }
      if ("byte".equals(typeName)) {
         return types.getPrimitiveType(TypeKind.BYTE);
      }
      if ("short".equals(typeName)) {
         return types.getPrimitiveType(TypeKind.SHORT);
      }
      if ("int".equals(typeName)) {
         return types.getPrimitiveType(TypeKind.INT);
      }
      if ("long".equals(typeName)) {
         return types.getPrimitiveType(TypeKind.LONG);
      }
      if ("float".equals(typeName)) {
         return types.getPrimitiveType(TypeKind.FLOAT);
      }
      if ("double".equals(typeName)) {
         return types.getPrimitiveType(TypeKind.DOUBLE);
      }
      TypeElement typeElement = elements.getTypeElement(typeName);
      if (typeElement == null) {
         throw new IllegalStateException("Type not found : " + typeName);
      }
      return typeElement.asType();
   }

   /**
    * A primitive type or void.
    */
   private final class MirrorPrimitiveType implements XClass, HasModelElement {

      private final Class<?> clazz;

      private final TypeMirror primitiveType;

      MirrorPrimitiveType(Class<?> clazz, TypeMirror primitiveType) {
         this.clazz = clazz;
         this.primitiveType = primitiveType;
      }

      @Override
      public XTypeFactory getFactory() {
         return MirrorTypeFactory.this;
      }

      @Override
      public Class<?> asClass() {
         throw new UnsupportedOperationException();
      }

      @Override
      public String getName() {
         return clazz.getName();
      }

      @Override
      public String getSimpleName() {
         return clazz.getSimpleName();
      }

      @Override
      public String getCanonicalName() {
         return clazz.getCanonicalName();
      }

      @Override
      public String getPackageName() {
         return null;
      }

      @Override
      public boolean isPrimitive() {
         return clazz != void.class;
      }

      @Override
      public boolean isEnum() {
         return false;
      }

      @Override
      public Iterable<? extends XEnumConstant> getEnumConstants() {
         throw new IllegalStateException(getName() + " is not an enum");
      }

      @Override
      public XEnumConstant getEnumConstant(String name) {
         throw new IllegalStateException(getName() + " is not an enum");
      }

      @Override
      public boolean isArray() {
         return false;
      }

      @Override
      public XClass getComponentType() {
         throw new IllegalStateException(getName() + " is not an array");
      }

      @Override
      public XClass getEnclosingClass() {
         return null;
      }

      @Override
      public XClass getSuperclass() {
         return null;
      }

      @Override
      public XClass[] getInterfaces() {
         return EMPTY_XCLASS_ARRAY;
      }

      @Override
      public String[] getGenericInterfaceParameterTypes(Class<?> c) {
         return null;
      }

      @Override
      public boolean isAssignableTo(XClass other) {
         if (this == other) {
            return true;
         }
         String secondTypeName = other.getCanonicalName();
         TypeMirror secondType = getTypeMirror(secondTypeName);
         return types.isSameType(primitiveType, secondType);
      }

      @Override
      public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
         return null;
      }

      @Override
      public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
         return null;
      }

      @Override
      public String getDocumentation() {
         return null;
      }

      @Override
      public int getModifiers() {
         return java.lang.reflect.Modifier.PUBLIC | java.lang.reflect.Modifier.FINAL;
      }

      @Override
      public XConstructor getDeclaredConstructor(XClass... argTypes) {
         return null;
      }

      @Override
      public Iterable<? extends XConstructor> getDeclaredConstructors() {
         return Collections.emptyList();
      }

      @Override
      public Iterable<? extends XMethod> getDeclaredMethods() {
         return Collections.emptyList();
      }

      @Override
      public XMethod getMethod(String methodName, XClass... argTypes) {
         return null;
      }

      @Override
      public Iterable<? extends XField> getDeclaredFields() {
         return Collections.emptyList();
      }

      @Override
      public boolean isLocal() {
         return false;
      }

      @Override
      public boolean equals(Object obj) {
         if (obj == this) {
            return true;
         }
         if (!(obj instanceof MirrorPrimitiveType)) {
            return false;
         }
         MirrorPrimitiveType other = (MirrorPrimitiveType) obj;
         return clazz == other.clazz;
      }

      @Override
      public int hashCode() {
         return clazz.hashCode();
      }

      @Override
      public String toString() {
         return clazz.toString();
      }

      @Override
      public Element getElement() {
         return types.asElement(primitiveType);
      }
   }

   /**
    * Only for declared types, not for primitives, arrays, or void.
    */
   private final class MirrorClass implements XClass, HasModelElement {

      private final DeclaredType typeMirror;

      private final TypeElement typeElement;

      private final Map<VariableElement, MirrorEnumConstant> enumConstants;

      private final Map<ExecutableElement, MirrorConstructor> constructorCache = new HashMap<>();

      private final Map<ExecutableElement, MirrorMethod> methodCache = new HashMap<>();

      private final Map<VariableElement, MirrorField> fieldCache = new HashMap<>();

      private final int modifiers;

      MirrorClass(DeclaredType typeMirror) {
         this.typeMirror = typeMirror;
         typeElement = (TypeElement) typeMirror.asElement();

         if (typeElement.getKind() == ElementKind.ENUM) {
            int[] ordinal = {0}; // assign ordinals in natural order
            enumConstants = typeElement.getEnclosedElements().stream()
                  .filter(e -> e.getKind() == ElementKind.ENUM_CONSTANT)
                  .map(e -> (VariableElement) e)
                  .collect(Collectors.toMap(
                        e -> e,
                        e -> new MirrorEnumConstant(this, e, ordinal[0]++),
                        (k, v) -> {
                           throw new IllegalStateException("Elements must be distinct");
                        },
                        LinkedHashMap::new)
                  );
         } else {
            enumConstants = null;
         }

         modifiers = getModifiersOfElement(typeElement);
      }

      @Override
      public XTypeFactory getFactory() {
         return MirrorTypeFactory.this;
      }

      @Override
      public Class<?> asClass() {
         throw new UnsupportedOperationException();
      }

      @Override
      public String getName() {
         return elements.getBinaryName(typeElement).toString();
      }

      @Override
      public String getSimpleName() {
         return typeElement.getSimpleName().toString();
      }

      @Override
      public String getCanonicalName() {
         return typeElement.getQualifiedName().toString();
      }

      @Override
      public String getPackageName() {
         PackageElement packageElement = elements.getPackageOf(typeElement);
         return packageElement.isUnnamed() ? null : packageElement.getQualifiedName().toString();
      }

      @Override
      public boolean isPrimitive() {
         return false;
      }

      @Override
      public boolean isEnum() {
         return enumConstants != null;
      }

      @Override
      public Iterable<? extends XEnumConstant> getEnumConstants() {
         if (enumConstants != null) {
            return enumConstants.values();
         }
         throw new IllegalStateException(getName() + " is not an enum");
      }

      @Override
      public XEnumConstant getEnumConstant(String name) {
         if (enumConstants == null) {
            throw new IllegalStateException(getName() + " is not an enum");
         }
         for (VariableElement v : enumConstants.keySet()) {
            if (name.equals(v.getSimpleName().toString())) {
               return enumConstants.get(v);
            }
         }
         return null;
      }

      @Override
      public boolean isArray() {
         return false;
      }

      @Override
      public XClass getComponentType() {
         throw new IllegalStateException(getName() + " is not an array");
      }

      @Override
      public XClass getEnclosingClass() {
         Element enclosingElement = typeElement.getEnclosingElement();
         return enclosingElement.getKind() == ElementKind.CLASS ? fromTypeMirror(enclosingElement.asType()) : null;
      }

      @Override
      public XClass getSuperclass() {
         TypeMirror superclass = typeElement.getSuperclass();
         return superclass.getKind() == TypeKind.DECLARED ? fromTypeMirror(superclass) : null;
      }

      @Override
      public XClass[] getInterfaces() {
         List<? extends TypeMirror> interfaces = typeElement.getInterfaces();
         XClass[] xclasses = new XClass[interfaces.size()];
         for (int i = 0; i < xclasses.length; i++) {
            xclasses[i] = fromTypeMirror(interfaces.get(i));
         }
         return xclasses;
      }

      @Override
      public String[] getGenericInterfaceParameterTypes(Class<?> c) {
         String name = c.getCanonicalName();
         if (name == null) {
            name = c.getName();
         }
         TypeMirror i = types.erasure(elements.getTypeElement(name).asType());
         return getGenericInterfaceParameterTypes(typeMirror, i);
      }

      private String[] getGenericInterfaceParameterTypes(TypeMirror typeMirror, TypeMirror i) {
         if (types.isAssignable(typeMirror, i)) {
            if (types.isSameType(types.erasure(typeMirror), i)) {
               return ((DeclaredType) typeMirror).getTypeArguments().stream()
                     .map((TypeMirror t) -> {
                        if (t instanceof TypeVariable) {
                           t = ((TypeVariable) t).getUpperBound();
                        }
                        return t.toString();
                     })
                     .toArray(String[]::new);
            }
            for (TypeMirror s : types.directSupertypes(typeMirror)) {
               String[] params = getGenericInterfaceParameterTypes(s, i);
               if (params != null) {
                  return params;
               }
            }
         }
         return null;
      }

      @Override
      public boolean isAssignableTo(XClass c) {
         if (this == c) {
            return true;
         }
         if (c.isPrimitive()) {
            // a non-primitive cannot be assignable to a primitive
            return false;
         }
         TypeMirror secondType = getTypeMirror(c.getCanonicalName());
         return types.isAssignable(types.erasure(typeMirror), types.erasure(secondType));
      }

      @Override
      public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
         return typeElement.getAnnotation(annotationClass);
      }

      @Override
      public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
         return typeElement.getAnnotationsByType(annotationClass);
      }

      @Override
      public String getDocumentation() {
         return DocumentationExtractor.getDocumentation(typeElement, fullyQualifiedAnnotations);
      }

      @Override
      public XMethod getMethod(String methodName, XClass... argTypes) {
         return cacheMethod(findExecutableElement(false, methodName, argTypes));
      }

      private ExecutableElement findExecutableElement(boolean isConstructor, String name, XClass[] argTypes) {
         Predicate<ExecutableElement> argFilter = e -> {
            if (e.getParameters().size() != argTypes.length) {
               return false;
            }
            List<? extends VariableElement> parameters = e.getParameters();
            for (int i = 0; i < argTypes.length; i++) {
               if (argTypes[i] != fromTypeMirror(parameters.get(i).asType())) {
                  return false;
               }
            }
            return true;
         };

         List<? extends Element> members = isConstructor ? typeElement.getEnclosedElements() : elements.getAllMembers(typeElement);
         return (ExecutableElement) members.stream()
               .filter(e -> isConstructor ? e.getKind() == ElementKind.CONSTRUCTOR : (e.getKind() == ElementKind.METHOD && name.equals(e.getSimpleName().toString())))
               .filter(e -> argFilter.test((ExecutableElement) e))
               .findFirst().orElse(null);
      }

      @Override
      public Iterable<? extends XField> getDeclaredFields() {
         return typeElement.getEnclosedElements().stream()
               .filter(e -> e.getKind() == ElementKind.FIELD)
               .map(e -> cacheField((VariableElement) e))
               .collect(Collectors.toList());
      }

      @Override
      public int getModifiers() {
         return modifiers;
      }

      @Override
      public boolean isLocal() {
         NestingKind nestingKind = typeElement.getNestingKind();
         return nestingKind == NestingKind.LOCAL || nestingKind == NestingKind.ANONYMOUS;
      }

      @Override
      public XConstructor getDeclaredConstructor(XClass... argTypes) {
         return cacheConstructor(findExecutableElement(true, null, argTypes));
      }

      @Override
      public Iterable<? extends XConstructor> getDeclaredConstructors() {
         return typeElement.getEnclosedElements().stream()
               .filter(e -> e.getKind() == ElementKind.CONSTRUCTOR)
               .map(e -> cacheConstructor((ExecutableElement) e))
               .collect(Collectors.toList());
      }

      @Override
      public Iterable<? extends XMethod> getDeclaredMethods() {
         return typeElement.getEnclosedElements().stream()
               .filter(e -> e.getKind() == ElementKind.METHOD)
               .map(e -> cacheMethod((ExecutableElement) e))
               .collect(Collectors.toList());
      }

      private MirrorMethod cacheMethod(ExecutableElement method) {
         if (method == null) {
            return null;
         }

         MirrorClass declaringClass = (MirrorClass) fromTypeMirror(method.getEnclosingElement().asType());
         MirrorMethod xmethod = declaringClass.methodCache.get(method);
         if (xmethod == null) {
            xmethod = new MirrorMethod(declaringClass, method);
            declaringClass.methodCache.put(method, xmethod);
         }
         return xmethod;
      }

      private MirrorConstructor cacheConstructor(ExecutableElement ctor) {
         if (ctor == null) {
            return null;
         }
         MirrorConstructor xctor = constructorCache.get(ctor);
         if (xctor == null) {
            xctor = new MirrorConstructor(this, ctor);
            constructorCache.put(ctor, xctor);
         }
         return xctor;
      }

      private MirrorField cacheField(VariableElement field) {
         MirrorClass declaringClass = (MirrorClass) fromTypeMirror(field.getEnclosingElement().asType());
         MirrorField xfield = declaringClass.fieldCache.get(field);
         if (xfield == null) {
            XEnumConstant enumConstant = field.getKind() == ElementKind.ENUM_CONSTANT ? declaringClass.enumConstants.get(field) : null;
            xfield = new MirrorField(declaringClass, field, enumConstant);
            declaringClass.fieldCache.put(field, xfield);
         }
         return xfield;
      }

      @Override
      public Element getElement() {
         return typeElement;
      }

      @Override
      public boolean equals(Object obj) {
         if (obj == this) {
            return true;
         }
         if (!(obj instanceof XClass)) {
            return false;
         }
         XClass other = (XClass) obj;
         return getName().equals(other.getName());
      }

      @Override
      public int hashCode() {
         return getName().hashCode();
      }

      @Override
      public String toString() {
         return typeMirror.toString();
      }
   }

   private final class MirrorEnumConstant implements XEnumConstant {

      private final XClass declaringClass;
      private final VariableElement e;
      private final int ordinal;
      private final int modifiers;

      MirrorEnumConstant(XClass declaringClass, VariableElement e, int ordinal) {
         this.declaringClass = declaringClass;
         this.e = e;
         this.ordinal = ordinal;
         this.modifiers = getModifiersOfElement(e);
      }

      @Override
      public int getOrdinal() {
         return ordinal;
      }

      @Override
      public String getName() {
         return e.getSimpleName().toString();
      }

      @Override
      public int getModifiers() {
         return modifiers;
      }

      @Override
      public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
         return e.getAnnotation(annotationClass);
      }

      @Override
      public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
         return e.getAnnotationsByType(annotationClass);
      }

      @Override
      public String getDocumentation() {
         return DocumentationExtractor.getDocumentation(e, fullyQualifiedAnnotations);
      }

      @Override
      public XClass getDeclaringClass() {
         return declaringClass;
      }
   }

   private final class MirrorArray implements XClass, HasModelElement {

      private final XClass componentType;

      MirrorArray(XClass componentType) {
         this.componentType = componentType;
      }

      @Override
      public XTypeFactory getFactory() {
         return MirrorTypeFactory.this;
      }

      @Override
      public Class<?> asClass() {
         throw new UnsupportedOperationException();
      }

      @Override
      public String getName() {
         return "[" + componentType.getName();
      }

      @Override
      public String getSimpleName() {
         return componentType.getSimpleName() + "[]";
      }

      @Override
      public String getCanonicalName() {
         String canonicalName = componentType.getCanonicalName();
         return canonicalName != null ? canonicalName + "[]" : null;
      }

      @Override
      public String getPackageName() {
         return componentType.getPackageName();
      }

      @Override
      public boolean isPrimitive() {
         return false;
      }

      @Override
      public boolean isEnum() {
         return false;
      }

      @Override
      public Iterable<? extends XEnumConstant> getEnumConstants() {
         throw new IllegalStateException(getName() + " is not an enum");
      }

      @Override
      public XEnumConstant getEnumConstant(String name) {
         throw new IllegalStateException(getName() + " is not an enum");
      }

      @Override
      public boolean isArray() {
         return true;
      }

      @Override
      public XClass getComponentType() {
         return componentType;
      }

      @Override
      public XClass getEnclosingClass() {
         return null;
      }

      @Override
      public XClass getSuperclass() {
         return null;
      }

      @Override
      public XClass[] getInterfaces() {
         return EMPTY_XCLASS_ARRAY;
      }

      @Override
      public String[] getGenericInterfaceParameterTypes(Class<?> c) {
         return null;
      }

      @Override
      public boolean isAssignableTo(XClass c) {
         if (this == c) {
            return true;
         }
         if (!c.isArray()) {
            return false;
         }
         return componentType.isAssignableTo(c.getComponentType());
      }

      @Override
      public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
         return null;
      }

      @Override
      public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
         return null;
      }

      @Override
      public String getDocumentation() {
         return null;
      }

      @Override
      public XMethod getMethod(String methodName, XClass... argTypes) {
         return null;
      }

      @Override
      public Iterable<? extends XField> getDeclaredFields() {
         return null;
      }

      @Override
      public int getModifiers() {
         return java.lang.reflect.Modifier.PUBLIC | java.lang.reflect.Modifier.FINAL;
      }

      @Override
      public boolean isLocal() {
         return false;
      }

      @Override
      public XConstructor getDeclaredConstructor(XClass... argTypes) {
         return null;
      }

      @Override
      public Iterable<? extends XConstructor> getDeclaredConstructors() {
         return Collections.emptyList();
      }

      @Override
      public Iterable<? extends XMethod> getDeclaredMethods() {
         return Collections.emptyList();
      }

      @Override
      public boolean equals(Object obj) {
         if (obj == this) {
            return true;
         }
         if (!(obj instanceof XClass)) {
            return false;
         }
         XClass other = (XClass) obj;
         return other.isArray() && getName().equals(other.getName());
      }

      @Override
      public int hashCode() {
         return getName().hashCode();
      }

      @Override
      public String toString() {
         return "[" + componentType.toString();
      }

      @Override
      public Element getElement() {
         return ((HasModelElement) componentType).getElement();
      }
   }

   private final class MirrorMethod implements XMethod, HasModelElement {

      private final MirrorClass declaringClass;

      private final ExecutableElement executableElement;

      private final int modifiers;

      MirrorMethod(MirrorClass declaringClass, ExecutableElement executableElement) {
         this.declaringClass = declaringClass;
         this.executableElement = executableElement;
         this.modifiers = getModifiersOfElement(executableElement);
      }

      @Override
      public XClass getReturnType() {
         return fromTypeMirror(executableElement.getReturnType());
      }

      @Override
      public XClass determineRepeatedElementType() {
         XClass returnType = determineOptionalReturnType();
         if (returnType.isArray()) {
            return returnType.getComponentType();
         }
         if (returnType.isAssignableTo(Collection.class)) {
            List<? extends TypeMirror> typeArguments = ((DeclaredType) unwrapOptionalReturnType()).getTypeArguments();
            if (typeArguments.size() == 1) {
               TypeMirror arg = typeArguments.get(0);
               return fromTypeMirror(arg);
            }
         }
         throw new IllegalStateException("Not a repeatable field");
      }

      @Override
      public XClass determineOptionalReturnType() {
         return fromTypeMirror(unwrapOptionalReturnType());
      }

      private TypeMirror unwrapOptionalReturnType() {
         if (getReturnType() == fromClass(Optional.class)) {
            return ((DeclaredType) executableElement.getReturnType()).getTypeArguments().get(0);
         }
         return executableElement.getReturnType();
      }

      @Override
      public int getParameterCount() {
         return executableElement.getParameters().size();
      }

      @Override
      public String[] getParameterNames() {
         return executableElement.getParameters().stream().map(p -> p.getSimpleName().toString()).toArray(String[]::new);
      }

      @Override
      public XClass[] getParameterTypes() {
         return executableElement.getParameters().stream().map(p -> fromTypeMirror(p.asType())).toArray(XClass[]::new);
      }

      @Override
      public String getName() {
         return executableElement.getSimpleName().toString();
      }

      @Override
      public int getModifiers() {
         return modifiers;
      }

      @Override
      public XClass getDeclaringClass() {
         return declaringClass;
      }

      @Override
      public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
         return executableElement.getAnnotation(annotationClass);
      }

      @Override
      public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
         return executableElement.getAnnotationsByType(annotationClass);
      }

      @Override
      public String getDocumentation() {
         return DocumentationExtractor.getDocumentation(executableElement, fullyQualifiedAnnotations);
      }

      @Override
      public Element getElement() {
         return executableElement;
      }

      @Override
      public boolean equals(Object obj) {
         if (obj == this) {
            return true;
         }
         if (obj == null || obj.getClass() != MirrorMethod.class) {
            return false;
         }
         return executableElement.equals(((MirrorMethod) obj).executableElement);
      }

      @Override
      public int hashCode() {
         return executableElement.hashCode();
      }

      @Override
      public String toString() {
         StringBuilder sb = new StringBuilder();
         for (Modifier m : Modifier.values()) {
            if (executableElement.getModifiers().contains(m)) {
               sb.append(m).append(' ');
            }
         }
         sb.append(executableElement.getReturnType())
               .append(' ').append(executableElement.getEnclosingElement().getSimpleName())
               .append('.').append(executableElement);
         return sb.toString();
      }

      @Override
      public String toGenericString() {
         return toString();
      }
   }

   private final class MirrorConstructor implements XConstructor {

      private final MirrorClass c;

      private final ExecutableElement executableElement;

      private final int modifiers;

      MirrorConstructor(MirrorClass c, ExecutableElement executableElement) {
         this.c = c;
         this.executableElement = executableElement;
         this.modifiers = getModifiersOfElement(executableElement);
      }

      @Override
      public int getParameterCount() {
         return executableElement.getParameters().size();
      }

      @Override
      public String[] getParameterNames() {
         return executableElement.getParameters().stream().map(p -> p.getSimpleName().toString()).toArray(String[]::new);
      }

      @Override
      public XClass[] getParameterTypes() {
         return executableElement.getParameters().stream().map(p -> fromTypeMirror(p.asType())).toArray(XClass[]::new);
      }

      @Override
      public String getName() {
         return executableElement.getSimpleName().toString();
      }

      @Override
      public int getModifiers() {
         return modifiers;
      }

      @Override
      public XClass getDeclaringClass() {
         return c;
      }

      @Override
      public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
         return executableElement.getAnnotation(annotationClass);
      }

      @Override
      public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
         return executableElement.getAnnotationsByType(annotationClass);
      }

      @Override
      public String getDocumentation() {
         // no @ProtoDoc allowed on constructors
         return null;
      }

      @Override
      public boolean equals(Object obj) {
         if (obj == this) {
            return true;
         }
         if (obj == null || obj.getClass() != MirrorConstructor.class) {
            return false;
         }
         return executableElement.equals(((MirrorConstructor) obj).executableElement);
      }

      @Override
      public int hashCode() {
         return executableElement.hashCode();
      }

      @Override
      public String toString() {
         StringBuilder sb = new StringBuilder();
         for (Modifier m : Modifier.values()) {
            if (executableElement.getModifiers().contains(m)) {
               sb.append(m).append(' ');
            }
         }
         sb.append(executableElement);
         return sb.toString();
      }

      @Override
      public String toGenericString() {
         return toString();
      }
   }

   private final class MirrorField implements XField {

      private final MirrorClass c;

      private final VariableElement field;

      private final XEnumConstant enumConstant;

      private final int modifiers;

      MirrorField(MirrorClass c, VariableElement field, XEnumConstant enumConstant) {
         this.c = c;
         this.field = field;
         this.enumConstant = enumConstant;
         this.modifiers = getModifiersOfElement(field);
      }

      @Override
      public XClass getType() {
         return fromTypeMirror(field.asType());
      }

      @Override
      public XClass determineRepeatedElementType() {
         if (getType().isArray()) {
            return getType().getComponentType();
         }
         if (getType().isAssignableTo(Collection.class)) {
            List<? extends TypeMirror> typeArguments = ((DeclaredType) field.asType()).getTypeArguments();
            if (typeArguments.size() == 1) {
               TypeMirror arg = typeArguments.get(0);
               return fromTypeMirror(arg);
            }
         }
         throw new IllegalStateException("Not a repeatable field");
      }

      @Override
      public boolean isEnumConstant() {
         return enumConstant != null;
      }

      @Override
      public XEnumConstant asEnumConstant() {
         if (enumConstant != null) {
            return enumConstant;
         }
         throw new IllegalStateException(getName() + " is not an enum constant");
      }

      @Override
      public String getName() {
         return field.getSimpleName().toString();
      }

      @Override
      public int getModifiers() {
         return modifiers;
      }

      @Override
      public XClass getDeclaringClass() {
         return c;
      }

      @Override
      public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {
         return field.getAnnotation(annotationClass);
      }

      @Override
      public <A extends Annotation> A[] getAnnotationsByType(Class<A> annotationClass) {
         return field.getAnnotationsByType(annotationClass);
      }

      @Override
      public String getDocumentation() {
         return DocumentationExtractor.getDocumentation(field, fullyQualifiedAnnotations);
      }

      @Override
      public boolean equals(Object obj) {
         if (obj == this) {
            return true;
         }
         if (obj == null || obj.getClass() != MirrorField.class) {
            return false;
         }
         return field.equals(((MirrorField) obj).field);
      }

      @Override
      public int hashCode() {
         return field.hashCode();
      }

      @Override
      public String toString() {
         return field.toString();
      }
   }
}

redpajama_set_name: RedPajamaGithub